Socket:关于read()和readLine()不返回-1导致跳不出循环

本文探讨了在客户端与服务器间进行文件传输时遇到的阻塞问题,并提出了三种解决方案:客户端通知服务端发送完成、在数据头部指定文件长度以及设置超时时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

部分源码:

        fout = new FileOutputStream(file);
	din = new DataInputStream(socket.getInputStream());
	byte[] bytes = new byte[1024];  
	int length = 0;
	while ((length = din.read(bytes, 0, bytes.length)) != -1) {
		fout.write(bytes, 0, length);
		fout.flush();
		System.out.println(length);
	}
    System.out.println("---------文件接收成功---------");

 如上,当文件写入完成后,发现服务器一直不打印

"---------文件接收成功---------"

得知length一直不等于-1导致跳不出循环

然后我试着在循环中打印了length,结果也只打印了一次就停止了。

之后又查看了下read的源码,发现如果按源码所说当读到文件结束后就会返回-1。

因此得出结论是din流尚未结束,然后往上追溯可看到din是由socket.getInputStream()获得的,

因此可以知道din流一直在等待客户端继续发送文件或信息,也就是read()方法在这个时候阻塞了。

总结下就是客户端和服务器建立了一条链接,客户端把文件发送完后就走了,服务器也不知道客户端发完了没,一直在傻傻的等,于是阻塞就发生了。

那我们怎么解决阻塞呢?

上网查了下有以下几种方法:

1、客户端告诉服务端我发完了,在发送的那一端(也就是客户端)调用socket.shutdownOutput();这样服务器端就知道文件发送结束了,read方法就会返回-1

2、发送数据时,在数据首部给定文件长度,当接受完给定长度后手动跳出循环。

3、在服务器端设置超时,比如3秒:

socket.setSoTimeout(3000);

如果read()方法在固定时间内没有读到数据的话就会抛出异常

参考博客:https://blog.youkuaiyun.com/fw0124/article/details/41227543

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值