关于socket编程 read时候阻塞的问题

小个子程序员2 2017-08-13 05:37:36
服务器代码

public class Server1 {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {

File file=new File("server.txt");
if(file.exists())
file.delete();
String m = "";
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "....connected....");
m = ip + "....connected....\n";
InputStream in = s.getInputStream();
int len = 0;
byte[] buf = new byte[1024];
while((len = in.read(buf)) != -1){
m += new String(buf);
};
//System.out.println(new String(buf, 0, len));

OutputStream os=s.getOutputStream();
os.write("饭菜马上到".getBytes());
os.close();
s.close();
ss.close();

FileOutputStream fos = new FileOutputStream(file);
fos.write(m.getBytes());
}
}

客户端代码

public class Client1 {
public static void main(String[] args){

File file=new File("client.txt");
if(file.exists())
file.delete();
try {
Socket s = new Socket("127.0.0.1", 10002);
OutputStream out = s.getOutputStream();
out.write("我肚子饿了".getBytes());
String m = "我肚子饿了\n";
InputStream is = s.getInputStream();
byte buf[] = new byte[1024];
int len = 0;
while((len = is.read(buf)) != -1){

m += new String(buf);
}
//System.out.println(new String(buf, 0, len));
s.close();

FileOutputStream fos = new FileOutputStream(file);
fos.write(m.getBytes());
} catch (Exception e) {
// TODO: handle exception
}
}
}

服务器运行到read方法,会执行一个循环,然后阻塞,请问是什么问题,能告诉我下原理和解决方式吗?
...全文
280 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 1 楼 dyc12ii 的回复:
read本身就是阻塞式方法,你产生死锁的原因是: 客户端发送数据以后,就进入了read状态,在等待,然而输出流没有关闭,所以客户端接收到你的数据,觉得还没读完,也在那等着读,两边都阻塞产生了死锁 解决方案:客户端发送 out.write("我肚子饿了".getBytes()); 之后,再发送一个结束标记 ,比如 : out.write("over".getBytes()); 服务端循环读取时,读到"over"视为结束,跳出循环 这样做可以解决你的现状,但其实有个问题: over这个结束标记并不是很好,因为如果你发送的信息中如果本身就含有"over"的话,就会产生干扰,最好换一个独特的结束标记.
问题已解决,客户端输出结束时加一句,shutdownoutput()就可以了。当然你的方法也可以
你好sun悟空 2017-08-14
  • 打赏
  • 举报
回复
read本身就是阻塞式方法,你产生死锁的原因是: 客户端发送数据以后,就进入了read状态,在等待,然而输出流没有关闭,所以客户端接收到你的数据,觉得还没读完,也在那等着读,两边都阻塞产生了死锁 解决方案:客户端发送 out.write("我肚子饿了".getBytes()); 之后,再发送一个结束标记 ,比如 : out.write("over".getBytes()); 服务端循环读取时,读到"over"视为结束,跳出循环 这样做可以解决你的现状,但其实有个问题: over这个结束标记并不是很好,因为如果你发送的信息中如果本身就含有"over"的话,就会产生干扰,最好换一个独特的结束标记.

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧