黑马程序员技术交流社区

标题: 网络编程---文件复制 [打印本页]

作者: 聂斌    时间: 2013-3-12 12:06
标题: 网络编程---文件复制
本帖最后由 聂斌 于 2013-3-12 13:12 编辑

客户端:

public class TextClient4 {

        public static void main(String[] args) throws UnknownHostException, IOException {
                // TODO Auto-generated method stub
                //建立socket服务指定数据要发到哪里去
                Socket s=new Socket("192.168.1.101",11800);
               
                //创建客户端的源,源是要读取的文件
                BufferedReader bufr=new BufferedReader(new FileReader("c:\\xx.txt"));
                //目的是socket输出流
                BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
               
               
                String num=null;
                while((num= bufr.readLine())!=null){
                   bufw.write(num);
                   //记得换行
                   bufw.newLine();
                   //把缓冲区里的数据刷新出去
                   bufw.flush();
                }
         
           //发送一个结束标记
                bufw.write("over");
                bufw.newLine();
                bufw.flush();
//                //关闭socket的输出流
//                s.shutdownOutput();
               
               
                //读取服务器端发回来的数据
                //获取socket的输入流读取服务器返回来的数据
                BufferedReader bufe=new BufferedReader(new InputStreamReader(s.getInputStream()));
               
                String fu= bufe.readLine();
                System.out.println(fu);
                //关闭流
                bufr.close();
               
                s.close();
               
               
        }


服务器端:

public class TextServer4 {

        public static void main(String[] args) throws IOException {
                // TODO Auto-generated method stub
                //创建socket,并设置监听端口
                ServerSocket sr=new ServerSocket(11800);
                //获取客户端对象
                Socket s=sr.accept();
                //获取客户端的ip
                String ip = s.getInetAddress().getHostAddress();
                System.out.println(ip+"....connected");
               
                //获取客户端的输入流,把数据写到文件里,,源是s.getInputStream()
                BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));
                //定义服务器的目的        
                BufferedWriter bW=new BufferedWriter(new FileWriter("c:\\textser.txt"));
               
                //读取从客户端发来的数据并写到文件里
                String num=null;
                while((num=bufr.readLine())!=null){
                        
                        if ("over".equals(num)) {
                                break;
                        }
                        
                        bW.write(num);
                        
                        bW.newLine();
                        //刷新
                        bW.flush();
                }
        
                //之后服务器回复个信息给客户端,,,
                //获取客户端的输出流
                BufferedWriter bWr=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
               
                bWr.write("你好我收到你的数据了");
                bWr.flush();
                //关闭流
                bWr.close();
                s.close();
                sr.close();
        }

}


代码的运行结果是正常:

我想问的是:
客户端的while循环结束后代表的是发送完了文件里的数据了,,但是后面为什么还得发送个over结束标记给服务器端,,而且over之后的那句bufw.newLine();还不能省略,,也就是发送完over后还得换行,,,,,,为什么over之后还得换行

同时发现:我 c:\\xx.txt 文件里的数据最末尾我加上换行了但是服务器还是没有把数据读取完,,服务器里的readLine()还得等待,,,这又是为什么,,,我 c:\\xx.txt 文件里的数据最末尾我不是加上了换行标记了吗怎么服务器里的 readLine()还在等待呢?????

当然了我根据老师的方法把代码修改了下,,,,结果就是正常的了

客户端:
  while((num= bufr.readLine())!=null){
                   bufw.write(num);
                   //记得换行
                   bufw.newLine();
                   //把缓冲区里的数据刷新出去
                   bufw.flush();
                }

               //关闭socket的输出流
                s.shutdownOutput();


服务器:

          while((num=bufr.readLine())!=null){

                        bW.write(num);
                        
                        bW.newLine();
                        //刷新
                        bW.flush();
                }






作者: 王亚东    时间: 2013-3-12 12:44
首先,使用BufferedReader的readLine方法时,是读取一行,返回的数据是除去换行符的,这也是为什么你在client端的while中手动newLine的原因(不手动,server端的没有换行)。
其次,readLine方法结束的条件就是读取到换行符,没有换行符,该方法堵塞,over后下换行符。
而在文件中加的换行标记,在readLine的时候是被去除的,所以在文件末尾加再多换行符也是无效的。
s.shutdownOutput(); 方法中封装并预定义了结束标记

作者: BitmapFactory    时间: 2013-3-12 12:45
我想问的是:
客户端的while循环结束后代表的是发送完了文件里的数据了,,但是后面为什么还得发送个over结束标记给服务器端,,而且over之后的那句bufw.newLine();还不能省略,,也就是发送完over后还得换行,,,,,,为什么over之后还得换行

同时发现:我 c:\\xx.txt 文件里的数据最末尾我加上换行了但是服务器还是没有把数据读取完,,服务器里的readLine()还得等待,,,这又是为什么,,,我 c:\\xx.txt 文件里的数据最末尾我不是加上了换行标记了吗怎么服务器里的 readLine()还在等待呢?????

第一个问题:因为readLine读数据读到\r\n会把读到的数据返回给num但不包含结束标记,由此,你把文件里的东西全发送完了,但没有任何结束标记,而readLine是基于read的是阻塞式的,它会一直等待数据,所以加个over结束标记,告诉它:我写完了,它读到over的时候代表它知道这个事了,而readLine返回给num却是在碰到\r\n才会返给num,newLine是为了让它返回,不然它会一直等待数据,newLine的好处是可以跨平台,不管是Linux里,还是Windows里,它都代表换行,而readLine返回就是读到换行才返回值

上面的回答也可以解释你的第二个问题
如果你在xx.txt文件最后一行加入一个over就可以注释客户端下面的三句话
                bufw.write("over");
                bufw.newLine();
                bufw.flush();




作者: 聂斌    时间: 2013-3-12 13:02
王亚东 发表于 2013-3-12 12:44
首先,使用BufferedReader的readLine方法时,是读取一行,返回的数据是除去换行符的,这也是为什么你在clie ...

呵呵懂了,,忽略了-------在文件中加的换行标记,在readLine的时候是被去除的,所以在文件末尾加再多换行符也是无效的。
作者: 聂斌    时间: 2013-3-12 13:05
张学林 发表于 2013-3-12 12:45
我想问的是:
客户端的while循环结束后代表的是发送完了文件里的数据了,,但是后面为什么还得发送个over结束 ...

呵呵同时也谢谢学林兄的热情解答,,,,
作者: 王浩威    时间: 2013-3-12 13:41
解答后..怎么看不到技术分啊..
作者: 聂斌    时间: 2013-3-12 15:49
王芝 发表于 2013-3-12 14:29
//发送一个结束标记
                bufw.write("over");
                bufw.newLine();

PrintWriter out = new PrintWriter(s.getOutputStream(),true);
我是写过的,,我就想看看自己做个结束标记的效果,,,自己还写个了时间戳作为结束标记




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