黑马程序员技术交流社区

标题: 在实践tcp协议socket上传图片中遇到的错误[已解决] [打印本页]

作者: 徐小骥    时间: 2012-8-15 14:16
标题: 在实践tcp协议socket上传图片中遇到的错误[已解决]
本帖最后由 徐小骥 于 2012-8-15 17:14 编辑
  1. import java.io.*;
  2. import java.net.*;


  3. public class tcpserver {
  4.         public static void main(String[] args) throws Exception {
  5.                 ServerSocket ss=new ServerSocket(10010);//创建绑定到特定端口的服务器套接字。
  6.                 while(true){//循环接受连接
  7.                         Socket s=ss.accept();//侦听并接受到此套接字的连接。
  8.                 new Thread(new picthread(s)).start();//启动线程实现多连接
  9.                 }
  10.         }
  11.         
  12. }
  13. class picthread implements Runnable{
  14.         private Socket st;
  15.         picthread(Socket st){
  16.                 this.st=st;
  17.         }
  18.         public void run() {
  19.         String ip=st.getInetAddress().getHostName();//获得连接主机的ip
  20.         int num=1;//文件,名变量
  21.         try {
  22.                 InputStream in=st.getInputStream();//获得套接字的输入流
  23.                 File f=new File(ip+"("+num+")"+".jpg");//创建源文件对象
  24.                 while(f.exists()){//判断是否存在
  25.                         f=new File(ip+"("+(num++)+")"+".jpg");//自定义的文件命名规则
  26.                 }
  27.                 FileOutputStream fos=new FileOutputStream(f);//打开文件输出流,并指定了源文件的文件名和路径
  28.                 byte[] by=new byte[1024];
  29.                 int len=0;
  30.                 while((len=in.read(by))!=-1){
  31.                         fos.write(by, 0, len);//将数据写入文件
  32.                 }
  33.                //System.out.print("!!!!"+ip);//程序运行到此处发生了阻塞,未打印
  34.                 OutputStream out=st.getOutputStream();//获取套接字的输出流
  35.                 out.write("上传成功".getBytes());//给连接主机反馈内容
  36.                 fos.close();//关闭IO流
  37.                 st.close();//关闭Socket流
  38.         } catch (IOException e) {
  39.              throw new RuntimeException(ip+"上传失败");
  40.         }        
  41.         }
  42. }
复制代码
  1. import java.io.*;
  2. import java.net.*;

  3. public class tcpclient{
  4.         public static void main(String[] args) throws Exception {
  5.      Socket st= new Socket("127.0.0.1",10010);// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
  6.      FileInputStream fim=new FileInputStream("f:\\01.jpg");//打开文件输入流并指定源文件
  7.      OutputStream out=st.getOutputStream();//得到套接字的输出流
  8.      byte[] bt=new byte[1024];
  9.      int len=0;
  10.      while((len=fim.read(bt))!=-1){
  11.              out.write(bt, 0, len);//将源文件数据按指定大小传给输出流
  12.      }
  13.      InputStream in=st.getInputStream();//得到套接字的输入流
  14.      byte[] bti=new byte[1024];
  15.      int num=in.read(bti);//获得输入流发送的数据长度  
  16. //程序运行到此处发生了阻塞,未打印
  17.     System.out.print("通过运行");//未打印
  18.      System.out.println(new String(bti,0,num));//打印输入流数据
  19.      fim.close();//关闭IO流
  20.      st.close();//关闭Socket流
  21.         }
  22. }
复制代码
代码如上,客户端运行到socket的接受流、服务端运行到socket的输入流都没有运行了,文件上传能成功,但是客户端在调用in.read()方法时发生了阻塞?而服务器在获取套接字的输出流之前发生了阻塞?两个控制台都没有反应,后面的代码都没有运行了,需要修改什么地方才能实现多个客户端向服务器上传图片?为什么它们没有运行了?

作者: 栗学魁    时间: 2012-8-15 14:36
在网吧,我记得是有一条一语是防阻塞的,你修下试试

while((len=fim.read(bt))!=-1){

             out.write(bt, 0, len);//将源文件数据按指定大小传给输出流

     }
在后面加条语句,
st.shutdownOuput();//这条语句就是说话客户端的输出数据结束,后面 的read方法就不会在阻塞等待读取了

作者: 徐小骥    时间: 2012-8-15 14:50
栗学魁 发表于 2012-8-15 14:36
在网吧,我记得是有一条一语是防阻塞的,你修下试试

while((len=fim.read(bt))!=-1){

试过了 还是没用
作者: 王程    时间: 2012-8-15 15:32
我把楼主的程序试了一下,就是只要添加一句st.shutdownOuput();就可以正常运行了呀
作者: 徐小骥    时间: 2012-8-15 15:53
王程 发表于 2012-8-15 15:32
我把楼主的程序试了一下,就是只要添加一句st.shutdownOuput();就可以正常运行了呀 ...

怎么我的还是卡着没动啊、、、
作者: 王程    时间: 2012-8-15 16:04
这个真心没招了{:soso_e110:}
作者: 徐小骥    时间: 2012-8-15 16:06
徐小骥 发表于 2012-8-15 15:53
怎么我的还是卡着没动啊、、、

okl但是程序为什么会堵塞?
作者: 徐小骥    时间: 2012-8-15 16:06
栗学魁 发表于 2012-8-15 14:36
在网吧,我记得是有一条一语是防阻塞的,你修下试试

while((len=fim.read(bt))!=-1){

程序为什么会发生这种堵塞?
作者: 程有愿    时间: 2012-8-15 16:39
这里是因为你的tcpclient里的socket的输出流对应着ServerSocket里面的输入流,而这个输入流里的read()方法是阻塞是方法,也就是你的当你没有给给这个方法设定一个结束标记时,它就会一直等待,(以为还没有读完),所以就在与其对应的socket里面的输入流的后面加上一句表示符,告诉数据已经输入完毕,这句语句也就是st.shutdownoutput();
作者: 徐小骥    时间: 2012-8-15 16:47
程有愿 发表于 2012-8-15 16:39
这里是因为你的tcpclient里的socket的输出流对应着ServerSocket里面的输入流,而这个输入流里的read()方 ...

明白了,也就是在客户端中我只给文件指定了结束标记,但是没有指定out流的结束标记,所以out一直在运行而in流一直阻塞?
作者: 程有愿    时间: 2012-8-15 16:50
是的呀,呵呵
作者: 徐小骥    时间: 2012-8-15 17:13
谢谢,搞清楚了
作者: 徐小骥    时间: 2012-8-15 17:13
问题已解决




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