用JavaSeverSocket和Socket实现的TCP服务器-客户端卡死的问题?

本文探讨了在服务器-客户端Demo中使用缓存字节流导致的卡死问题,揭示了同一Socket对象引发的并发读写冲突。通过实例和解决策略,解释了为何简单数组接收能正常工作,而循环读取则导致问题。重点在于正确处理并发和避免资源竞争。

在写一个简单的服务器-客户端Demo时,想使用效率更高的缓存字节流来接收从Socket获取的字节流,结果发现出了服务器和客户端卡死的问题
修改前
【一开始是的思路是,缓存流用到了缓存机制,我没用flush刷新,是不是因为这样卡死在缓存里了。(思路错误,因为我是输入用的缓存流,输出根本用缓存流)】

tip1:如果本例中,在客户端发送完信息后,就调用os.close()把输入流关闭,是客户端是会报错java.net.SocketException: Socket is closed的,因为- 如果此Scoket具有相关联的通道,则生成的OutputStream 的所有操作也关联该通道。关闭生成的OutputStream也将关闭相关的SocketInputStream也是一样的。

【发现方向错了之后,我又改用字节流试了一试,发现能正常运行,如下图。(其实问题还没有解决,因为我是图简单,直接用一个数组就一次性接收了传过来的数据)】
在这里插入图片描述

【貌似没有问题,但我想如果传入的数据量很大呢,于是改了用while循环获取的方式获取传入的数据,真的卡死了,如下图所示。】
在这里插入图片描述

终于水落石出了,其实是因为服务器跟客户端是用的同一个Socket对象啊!!!
step1:服务器启动,此时网络中还没有客户端向它发送Socket对象,它就阻塞在accept()方法等待Socket对象的到来,并与之建立连接。
step2:客户端启动,与目标服务器发送了Socket对象,建立了连接,然后调用了write方法向服务器发送了字节流,然后继续向下执行read方法准备获取字节流。
step3:服务器端收到字节流后,进入while循环使用read方法获取了一遍数据,然后第二次进行while循环使用read方法读取时,发现客户端也在使用通道调用read,他们同时占用了同一个socket对象的流read方法,于是卡死了。

解决方案:
用一个较大的字节数组去接收,一次性接收,不用while循环
在这里插入图片描述

正常情况下,应该是客户端发送指令请求,服务器执行对应操作。不必过于纠结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值