黑马程序员技术交流社区

标题: 通过TCP协议进行图片上传时遇到的问题 [打印本页]

作者: 孙国军    时间: 2012-4-26 12:28
标题: 通过TCP协议进行图片上传时遇到的问题
  1. /*
  2. 需求:
  3. 通过TCP的Socket和ServerSocket,向服务段上传图片;
  4. 思路:
  5. Socket服务:
  6. 1.想要上传图片,就需要使用IO字节流,把图片文件出入到Socket输出流,输出到服务端;
  7. 2.
  8. */
  9. import java.io.*;
  10. import java.net.*;

  11. class SocketClient implements Runnable
  12. {
  13. private Socket s;
  14. public SocketClient(Socket s)
  15. {
  16. this.s=s;
  17. }
  18. public void run()
  19. {
  20. File file=new File("yuanye.jpg");

  21. if (file.exists())
  22. {
  23. throw new RuntimeException("您想要上传的图片文件不存在");
  24. }
  25. BufferedInputStream bufr=null;
  26. try
  27. {
  28. bufr=new BufferedInputStream(new FileInputStream(file));
  29. byte buf[]=new byte[1024];

  30. int len=0;

  31. while ((len=bufr.read(buf))!=-1)
  32. {
  33. s.getOutputStream().write(buf,0,len);
  34. }
  35. }
  36. catch (FileNotFoundException fnfe)
  37. {
  38. throw new RuntimeException("关联文件到输入流失败");
  39. }
  40. catch (IOException ie)
  41. {
  42. throw new RuntimeException("上传文件失败");
  43. }
  44. finally
  45. {
  46. try
  47. {
  48. if (bufr!=null)
  49. {
  50. bufr.close();
  51. }
  52. }
  53. catch (IOException ioe)
  54. {
  55. throw new RuntimeException("关闭输入流失败");
  56. }
  57. }
  58. }
  59. }


  60. class SocketServer implements Runnable
  61. {
  62. private ServerSocket ss;
  63. public SocketServer(ServerSocket ss)
  64. {
  65. this.ss=ss;
  66. }
  67. public void run()
  68. {
  69. File file=new File("yuanye复件.jpg");
  70. PrintStream ps =null;
  71. Socket s=null;
  72. try
  73. {
  74. ps=new PrintStream(new BufferedOutputStream(new FileOutputStream(file)),true);
  75. s=ss.accept();

  76. byte[] buf=new byte[1024];
  77. int len=0;

  78. while ((len=s.getInputStream().read(buf))!=-1)
  79. {
  80. ps.println(buf);
  81. }
  82. }
  83. catch (FileNotFoundException fnfe)
  84. {
  85. throw new RuntimeException("关联文件到输出流失败");
  86. }
  87. catch (IOException ie)
  88. {
  89. throw new RuntimeException("读取文件失败");
  90. }
  91. finally
  92. {
  93. ps.close();

  94. try
  95. {
  96. if (s!=null)
  97. {
  98. s.close();
  99. }
  100. }
  101. catch (IOException i)
  102. {
  103. throw new RuntimeException("客服端关闭失败");
  104. }
  105. }

  106. }
  107. }

  108. class UploadingPictureByTCP
  109. {
  110. public static void main(String[] args) throws Exception
  111. {
  112. new Thread(new SocketClient(new Socket("192.168.0.4",10003))).start();
  113. new Thread(new SocketServer(new ServerSocket(10003))).start();
  114. }
  115. }
复制代码


作者: 高彰谦    时间: 2012-4-26 14:54
抱歉代码太多就没看了,你的异常是ConnectionException,也就是你在创建socket的时候就失败了,后面的代码根本就没有运行了
请问192.168.0.4是你本机的IP吗?  请你补充回答这个问题,然后再看其他问题
作者: 施俊    时间: 2012-4-26 15:24
我感觉是这样的,你把客户端和服务端封装成了两个线程,主线程先开启了客户端,此时服务端尚未开启,所以产生了连接异常,你可以试试先开启服务端。
不知道行不行,或者你搞个类让服务端一直等待着。
作者: 孙国军    时间: 2012-4-26 15:34
高彰谦 发表于 2012-4-26 14:54
抱歉代码太多就没看了,你的异常是ConnectionException,也就是你在创建socket的时候就失败了,后面的代码根 ...

是本机的
作者: 徐鑫    时间: 2012-4-26 15:36
本帖最后由 徐鑫 于 2012-4-26 15:37 编辑

Tcp是面向连接的,这个情况应该是楼主先开了客户端,导致的连接失败报错
public static void main(String[] args) throws Exception

{

new Thread(new SocketClient(new Socket("192.168.0.4",10003))).start();//这边先开了客户端导致链接失败报错,上下代码互换呢

new Thread(new SocketServer(new ServerSocket(10003))).start();

}

}
作者: 高彰谦    时间: 2012-4-26 16:25
你好,服务器端需要先开,而且,可能是服务器开启监听需要时间。
  1. new Thread(new SocketServer(new ServerSocket(10003))).start();
  2.                 Thread.sleep(10*1000);
  3.                 new Thread(new SocketClient(new Socket("127.0.0.1", 10003))).start();
复制代码
这样修改之后,起码可以建立连接了
作者: 高彰谦    时间: 2012-4-26 16:49
稍作改动,已经可以从客户端上传文件到服务器端了,
有几个地方需要改动
  1. if (!file.exists()) {
  2.                         throw new RuntimeException("您想要上传的图片文件不存在");
  3.                 }
复制代码
你没有加!,造成逻辑错误
我个人认为,写二进制文件没必要用PrintStream,我觉得PrintStream还是更加实用与字符操作,并且没有任何在操作二进制文件上的优势。

还有服务器端在接受文件数据时,while循环的退出条件不生效,因为socket.getInputStream.read(byte[] bytes),当没有数据读入时,处于阻塞状态,而不会返回-1

这就是我全部的认识了。




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