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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周恺 中级黑马   /  2012-7-6 01:14  /  1460 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 周恺 于 2012-7-18 08:12 编辑

今天看到毕老师的tcp复制文件的视频有点不明白:
  1. import java.io.*;
  2. import java.net.*;

  3. class TextClient
  4. {
  5. public static void main(String[] args) throws Exception
  6. {
  7. Socket s = new Socket("KLO-PC",10006);
  8. BufferedReader bufr =
  9. new BufferedReader(new FileReader("f://ArrayTest2.java"));
  10. PrintWriter out = new PrintWriter(s.getOutputStream(),true);
  11. String line = null;
  12. while((line=bufr.readLine())!=null)
  13. {
  14. out.println(line);
  15. }

  16. //s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1.
  17. BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
  18. String str = bufIn.readLine();
  19. System.out.println(str);
  20. bufr.close();
  21. s.close();
  22. }
  23. }
  24. class TextServer
  25. {
  26. public static void main(String[] args) throws Exception
  27. {
  28. ServerSocket ss = new ServerSocket(10006);
  29. Socket s = ss.accept();
  30. String ip = s.getInetAddress().getHostAddress();
  31. System.out.println(ip+"....connected");
  32. BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
  33. PrintWriter out = new PrintWriter(new FileWriter("f://ArrayTest2_copy.java"),true);
  34. String line = null;
  35. while((line=bufIn.readLine())!=null)
  36. {
  37. //if("over".equals(line))
  38. //break;
  39. out.println(line);
  40. }
  41. PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  42. pw.println("上传成功");
  43. out.close();
  44. s.close();
  45. ss.close();

  46. }
  47. }
复制代码
这是毕老师未修正的代码,他老人家说,这样写服务器端的readLine()方法会因为客户端没有传来停止标示会一直阻塞,这里我不太明白,while((line=bufIn.readLine())!=null)
不是有停止循环的条件了吗?readLine()运行到流结尾不就退出循环了吗?
我在看视频前自己写了一段代码:
  1. import java.net.*;
  2. import java.io.*;
  3. class TextClient
  4. {
  5. public static void main(String[] args)throws Exception
  6. {
  7. long startTime=System.currentTimeMillis();

  8. Socket s=new Socket("KLO-PC",10007);

  9. FileInputStream fis=new FileInputStream("d://javaAPI.chm");

  10. OutputStream nos=s.getOutputStream();

  11. byte buff[]=new byte[1024*1024];
  12. //byte buff;
  13. int len;

  14. while((len=fis.read(buff))!=-1)
  15. {
  16. nos.write(buff,0,len);
  17. //nos.write(buff);

  18. nos.flush();
  19. }
  20. //s.close();

  21. //fis.close();
  22. long overTime=System.currentTimeMillis();
  23. p.sop("传输时间为"+(overTime-startTime)+"毫秒");


  24. }
  25. }


  26. class TextServer
  27. {
  28. public static void main(String args[])throws Exception
  29. {
  30. ServerSocket ss=new ServerSocket(10007);
  31. Socket s=ss.accept();
  32. p.sopln("已接收到IP::"+s.getInetAddress().getHostAddress()+"::的连接....");
  33. InputStream nis=s.getInputStream();
  34. File f=new File("d://javaAPI.chm");
  35. FileOutputStream fos=new FileOutputStream(f);
  36. byte buff[]=new byte[1024*1024];
  37. int len;

  38. long fileLen=0;

  39. while ((len=nis.read(buff))!=-1)
  40. {
  41. fos.write(buff,0,len);
  42. fos.flush();

  43. fileLen+=f.length();

  44. p.sopln("已接收到"+fileLen+"字节");
  45. }
  46. p.sopln("接收完成");

  47. ss.close();

  48. fos.close();
  49. }
  50. }
复制代码
我使用的是字节流传输,但是我也是用了阻塞式方法read(),也没有从客户端传什么停止标识.为什么就可以正常传输呢?

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

1 个回复

倒序浏览
1.
Server那边
while((line=bufIn.readLine())!=null)是可以退出循环
但是Client那边在从一个文件里面读取时用的条件是while((line=bufr.readLine())!=null)
当Client读到文件结尾了 这个while循环就跳出去了
Client就不传东西过去了
Client知道文件到结尾了
但是没有告诉Server
所以Server那边还在等数据
s.shutdownOutput()就是告诉Server那边文件到结尾了

2.
毕老师的代码中,Client传完后,要等待Server传回一个"上传成功的信息"
所以也调用了read()阻塞方法
这样2边都在等待
就出问题了.
至于为什么你用字节流就可以正常传
我感觉是这样
如果Client那边传完之后不等Server的返回信息
直接把Socket给close了
那流也给close了
Server那边想等着read也等不了了
于是就正常结束了
不过我看你的代码里把s.close()注释掉了?
这样应该会有Server那边应该会有connection reset异常
但是文件还是传过去了
应该相当于强行中断了

评分

参与人数 2技术分 +1 黑马币 +5 收起 理由
职业规划-刘倩老师 + 1 赞一个!
周恺 + 5 谢谢,我明白了

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马