黑马程序员技术交流社区

标题: 分享解决TCP服务端客户端一次性交互read阻塞的问题 [打印本页]

作者: freehiker    时间: 2013-9-25 00:38
标题: 分享解决TCP服务端客户端一次性交互read阻塞的问题
服务端、客户端若是一次性交互,而这次交互的数据比较多,需要用到while循环的时候,用read判断的话会导致,即使数据完了还是会阻塞状态,这样之后,客户端和服务端都进入了等待状态。
其实在InputStream中,可以不通过read()方法判断流数据是否到达末尾,而通过available()判断,若available()!=0,流数据就未到达末尾,而它不是阻塞式方法,一次性交互的时候用这个判断可以避免进入等待状态
演示代码:
  1. /*
  2. 服务端
  3. */
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. import java.io.PrintWriter;
  7. import java.net.ServerSocket;
  8. import java.net.Socket;

  9. class TcpServer
  10. {
  11.         public static void main(String[] args) throws Exception
  12.         {
  13.                 ServerSocket ss = new ServerSocket(10000);
  14.                 Socket s = ss.accept();
  15.                 InputStream is = s.getInputStream();
  16.                 String ip = s.getInetAddress().getHostAddress();
  17.                 System.out.println(ip);
  18.                 byte[] buf =  new byte[1024];
  19.                 int len = 0;
  20.                 while((len=is.available())!=0) //判断流对象数据是否到达末尾
  21.                 {
  22.                         len=is.read(buf);//获取流对象数据长度
  23.                         String str = new String(buf,0,len);
  24.                         System.out.println(str);
  25.                 }
  26.                 PrintWriter os = new PrintWriter(s.getOutputStream(),true);
  27.                 os.println("send to client");
  28.                 s.close(); //关闭客户端对象
  29.                 ss.close(); //关闭服务器 这里可选,可关可不关
  30.         }
  31. }

  32. /*
  33. 客户端
  34. */
  35. import java.io.InputStream;
  36. import java.io.PrintWriter;
  37. import java.net.Socket;

  38. class TcpClient
  39. {
  40.     public static void main(String[] args) throws Exception
  41.     {
  42.         Socket s = new Socket("192.168.2.100",10000);
  43.         PrintWriter os = new PrintWriter(s.getOutputStream(),true);
  44.         os.println("send to server");
  45.         InputStream is = s.getInputStream();
  46.         byte[] buf = new byte[1024];
  47.         int len = 0;
  48.         while((len=is.read(buf))!=-1) //这里用这种循环其实也会进入等待状态,而因为服务器端传回“send to client”后就把s.close()关了,所以这里就算等待也会被结束掉。
  49.         {
  50.             System.out.println(new String(buf,0,len));
  51.         }
  52.         s.close();
  53.     }
  54. }
复制代码
关于上面的等待问题,本来想了很久 ,一直没有实现,后来查看InputStream的描述才想到了这个办法,这种代码演示又不像键盘录入可以判断输入了什么从而结束while的循环,所以感觉就只能通过这种方法实现了,如果有更好的方法,欢迎交流。


作者: 吴光新    时间: 2013-9-25 00:55
本帖最后由 吴光新 于 2013-9-25 01:56 编辑

不错,有思想

作者: freehiker    时间: 2013-9-25 08:28
吴光新 发表于 2013-9-25 00:55
不错,有思想

别舍不得技术分嘛,哈哈{:soso_e113:}





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