黑马程序员技术交流社区

标题: 关于socket 中的输出流关闭问题 [打印本页]

作者: 李厚斌    时间: 2014-3-24 00:32
标题: 关于socket 中的输出流关闭问题
本帖最后由 李厚斌 于 2014-3-25 12:31 编辑

刚学了网络编程这块。吧整个代码发了下。就是从本地的一个视频传到网络端
网络端我也定义了127.0.0.1。程序是没问题的。os.close();他的问题。
如果我放在代码所在的问题。就会报错。我在代码地方放了打印。可以判断出代码走到哪里出的错
BufferedInputStream bw=new BufferedInputStream(s.getInputStream());
//走到这就出错了。这两个不明明一个输出流一个输入流么。怎么相关呢??
搞不懂为什么呢???
os.close()把他放到代码尾部就能正常运行。。

class UserJpg
{
        public static void main(String[] args)throws Exception
        {
                Socket s=new Socket("127.0.0.1",10008);
                OutputStream os=s.getOutputStream();
                FileInputStream fs=new FileInputStream("989_1.rmvb");
                byte[] b=new byte[1024*1000*100];
                int len=0;
                while((len=fs.read(b))!=-1)
                {
                        os.write(b,0,len);
                }
                s.shutdownOutput();
                System.out.println("os.close();");
                os.close();//这里我明明关掉的是os的输出流。。为什么会报错呢
                //而放在下面就不会。。打印的是判断程序走到哪里出错的
                System.out.println("os.close(111);");
                BufferedInputStream bw=new BufferedInputStream(s.getInputStream());
                //走到这就出错了。这两个不明明一个输出流一个输入流么。怎么相关呢
                System.out.println("os.close(112);");
                byte[] b1=new byte[1024];
                int len1=bw.read(b1);
                String s1=new String(b1,0,len1);
                System.out.println(s1);
                fs.close();
                bw.close();
                s.close();
        }
}
class SumRun implements Runnable
{
        private Socket s;
        SumRun(Socket s)
        {
                this.s=s;
        }
        public void run()
        {
                int count=1;
                try
                {
                        System.out.println(s.getInetAddress().getHostAddress()+"连接成功");
                        InputStream in=s.getInputStream();
                        File f=new File(count+".rmvb");
                        while(f.exists())
                                f=new File((count++)+".rmvb");
                        FileOutputStream fo=new FileOutputStream(f);
                        byte[] b=new byte[1024*1000*100];
                        int len=0;
                        while((len=in.read(b))!=-1)
                        {
                                fo.write(b,0,len);
                        }

                        BufferedWriter bw=new BufferedWriter (new OutputStreamWriter(s.getOutputStream()));
                        bw.write("上传成功");
                        bw.flush();
                        in.close();
                        fo.close();        
                        s.close();
                }
                catch (Exception e)
                {
                        throw new RuntimeException("上传失败");
                }
               
        }

}
class Server
{
        public static void main(String[] args)throws Exception
        {
                ServerSocket ss=new ServerSocket(10008);
                while (true)
                {
                        Socket s=ss.accept();
                        new Thread(new SumRun(s)).start();
                }        
               
                //ss.close();
                                
        }
}
作者: 菠萝鱼    时间: 2014-3-24 10:39
自我理解 Socket是TCPIP通信,就像打电话一样,只要有一个Socket流关闭,这个通路就关闭了,不知道这样理解对不对?
作者: 霍振鹏    时间: 2014-3-25 02:24
本帖最后由 霍振鹏 于 2014-3-25 02:26 编辑

我们要注意一点:我们不管是调用s.getInputStream()还是s.getOutputStream(),s始终只有一个,而s有一个属性isClosed,初始状态为false,当你第一次调用os.close()时,

isClosed被赋值为true,
当调用s.getInputStream()时,

它是先执行checkOpenAndCreate(false)这个方法的,

而这个方法会首先去判断isClosed()的值

当然他会返回true,所以if为真,它抛出Socket is closed异常。

你可以试着再次调用os.getOutputStream(),也会抛出同样的异常。




哎 。。。。。。。有我截屏图片,弄不进去,你下载附件看看吧,有源码   


我忙了一晚上才弄明白,,,,,,给个技术分呗!!!

霍振鹏 (2).zip

30.47 KB, 下载次数: 121


作者: 疯狂沙漠    时间: 2014-3-25 09:31
你关闭输出流,而输出流来自socket里的,一旦关闭输出流,就等于关闭socket,所以在你获取socket的输入流的时候,会报出socket流已关闭。所以你上传操作完毕后直接关闭socket流就可以,也就关闭了输入输出流




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2