最近在写一个简单的socket示例时遇到一个问题,使用write.flush()目标端read接收不到数据,调用close()后数据可正常接收。这让我很是费解,记得当初学习flush方法时,都说明这个方法是强制将缓存区内容刷新到输出流中。难道是socket输出流有不一样。看到网上很多人在问这个问题,解释的也是五花八门的。后来我终于找到了原因,有这样疑惑的同胞们可以参考下,出问题的不是输出的逻辑,而是read方法。先上代码:
服务端Server.java:
try{
ServerSocket server = new ServerSocket(9090);
while(true){
Socket socket=server.accept();
System.out.println("接收到客户端"+socket.getInetAddress()+"连接请求");
Reader reader = new InputStreamReader(socket.getInputStream());
char chars[] = new char[64];
int len;
StringBuilder sb = new StringBuilder();
while ((len=reader.read(chars)) != -1) {
sb.append(new String(chars, 0, len));
}
System.out.println("接收到的信息:"+sb.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
客户端Client.java
Writer writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("还好啊");
writer.flush();
这是出问题的代码,服务端一直都没有输出内容,当时我误以为是没有接受到数据,后来查阅资料才知道问题出在read方法,这个方法如果没有数据会一直阻塞(而调用write.close()方法后,read会返回-1跳出while循环),所以如果你想在while循环外获取数据,有两个方法
1)客户端调用write.close()方法
2)服务端在while循环体中设定跳出条件,或是约定数据长度,或是发送字符串有结束标志。
修改代码如下:
客户端:
Writer writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("还好啊");
writer.write("eof");//eof为结束标记
writer.flush();
服务端在while循环体中添加如下代码:
while ((len=reader.read(chars)) != -1) {
sb.append(new String(chars, 0, len));
if(sb.toString().indexOf("eof")!=-1){
//判断结束标记
break;
}
}
结果服务端成功接收到消息,遇到同样困扰的同学们,看是不是和我犯了一样的错误。