A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 吴上波 于 2013-3-21 00:39 编辑

下面是文本文件上传的代码,关于流的关闭问题若干,请大家帮忙看看
客户端代码:
public class UploadClient {

        public static void main(String[] args) throws IOException {

                Socket s = new Socket("192.168.1.103", 10086);

                BufferedReader bufr = new BufferedReader(new FileReader(
                                "UploadClient.txt"));
                PrintWriter out = new PrintWriter(s.getOutputStream(), true);//这个流为什么不关闭了?什么时候关闭?

                String line = null;
                while ((line = bufr.readLine()) != null) {
                        out.println(line);
                }
               
                s.shutdownOutput();//为什么socket的输出流关闭之后,服务端才能跳出while()循环?

                BufferedReader bufin = new BufferedReader(new InputStreamReader(
                                s.getInputStream()));
                String str = bufin.readLine();
                System.out.println(str);

                bufr.close();
                s.close();
        }
}

下面是服务端代码:
public class UploadServer {

        public static void main(String[] args) throws IOException {
               
                ServerSocket ss = new ServerSocket(10086);
               
                Socket s = ss.accept();
               
                String ip = s.getInetAddress().getHostAddress();
                System.out.println(ip+"......连接");
               
                BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));//这个流为什么不在while()循环之后就关闭?
                PrintWriter pw = new PrintWriter(new FileWriter(System.currentTimeMillis()+"UploadServer.txt"),true);//为什么要关闭这个流了?
               
                String line = null;
                while((line= bufr.readLine())!= null){
                        pw.println(line);
                }
               
                PrintWriter out = new PrintWriter(s.getOutputStream(),true);
                out.println("上传成功!");
                pw.close();
                s.close();//这里为何再次关闭客户端流?
                ss.close();

        }

}



评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

7 个回复

倒序浏览
你说的那些流,都应该关闭,没关闭是为了赶时间,不严谨,并不是说不应该关;

至于 s.shutdownOutput();//为什么输出流关闭后,服务端就会跳出循环?  你这个注释的地方有问题,这句话是在客户端向服务器端写一个结束标记,你说的关闭输出流服务器跳出循环没理解什么意思,如果说是非正常关闭客户端,那么服务器会因为socket连接异常而退出;网络通信里,最容易遇到阻塞方法带来的困惑。
回复 使用道具 举报
看这大半夜的,大神估计都睡觉了,我来吧..哈哈哈哈
1. PrintWriter out = new PrintWriter(s.getOutputStream(), true);//这个流为什么不关闭了?不占资源吗?
这个流是通过通过Socket的方法获取的,后面又了s.close();那么流也就关掉了.
2. s.shutdownOutput();//为什么输出流关闭后,服务端就会跳出循环?
这句话是告诉服务端,客户端的数据写完了,那么服务端就会收到一个结束标记,所以服务端循环结束了..
3.BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));//这个流为什么不在while()循环之后就关闭?
这个流在循环结束后已经关闭了..不是有s.close()么..理由同1.
4. PrintWriter pw = new PrintWriter(new FileWriter(System.currentTimeMillis()+"UploadServer.txt"),true);//为什么要关闭这个流了?
这个流不是通过 s.getXXX()  而是new了一个FileWriter() 所以你关闭Socket也没用,需要单独关闭之.
5.  s.close();//这里为何再次关闭客户端流?
当上传结束后,关闭已经完成操作的客户端的连接,节省服务器的资源.嗯,就是这样.
楼主,有帮助么?

评分

参与人数 2技术分 +1 黑马币 +6 收起 理由
黄玉昆 + 1
MyNameIs520 + 6

查看全部评分

回复 使用道具 举报
VOIDMAIN 发表于 2013-3-21 00:26
你说的那些流,都应该关闭,没关闭是为了赶时间,不严谨,并不是说不应该关;

至于 s.shutdownOutput();// ...

我没有表达清楚
我的意思是: 客户端s.shutdownOutput()关闭之后,服务器端才能跳出while()循环,向客户端输出“上传成功!”,从而服务端和客户端的流都各自关闭
回复 使用道具 举报
  1. PrintWriter out = new PrintWriter(s.getOutputStream(), true);//这个流为什么不关闭了?不占资源吗?
  2. ------------------------------
  3. 因为是写入的socket流,在后面的s.close结束掉就跟着关闭了
复制代码
  1. s.shutdownOutput();//为什么输出流关闭后,服务端就会跳出循环?
  2. ----------------------------------------------------
  3. 因为会返回一个标记-1用作循环结束标记,所以会跳出循环
复制代码
  1. BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));//这个流为什么不在while()循环之后就关闭?

  2. ----------------------------------------
  3. 这个是有buffer的缓冲区
复制代码
  1. PrintWriter pw = new PrintWriter(new FileWriter(System.currentTimeMillis()+"UploadServer.txt"),true);//为什么要关闭这个流了?

  2. --------------------------------
  3. 这个是单独打印的流,和socket没关系,所以要单独关
复制代码
  1. s.close();//这里为何再次关闭客户端流?
  2. ---------------------------------
  3. 这里关的是服务器的读取的客户端socket流,和上面的S没关系
复制代码
这是我看过视频之后总结得出的

评分

参与人数 2技术分 +1 黑马币 +6 收起 理由
黄玉昆 + 1
MyNameIs520 + 6

查看全部评分

回复 使用道具 举报
哇靠,还以为给技术分了..原来个的是金币~~白白激动了一下...{:soso_e149:}
回复 使用道具 举报
谢洋 高级黑马 2013-3-21 00:55:48
7#
s.shutdownOutput();//为什么输出流关闭后,服务端就会跳出循环?
可以这么说客户端和服务端处理数据:是同一个socket对象,当客户端s.shutdownOutput(),会往服务端的Socket对象发送一个结束标志,当服务端的Socket对象收到结束标记后就会跳出循环。
   while((line= bufr.readLine())!= null){
                        pw.println(line);
                }
//从这段代码来看,可以推出Socket 的InputStream对象内应该封装了对结束标志的处理方法,当Socket的inputStream收到结束标志后就会执行该方法来跳出循环。
因整段代码只看到InputStream在执行。致于内部具体怎么做的到,不了解。
可以通过在服务端做一个测:也shutDown一下,让客户端跳循环。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
谢洋 发表于 2013-3-21 00:55
s.shutdownOutput();//为什么输出流关闭后,服务端就会跳出循环?
可以这么说客户端和服务端处理数据:是同 ...

非常感谢,我去看看SRC
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马