在写一个简单的服务器-客户端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循环

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

被折叠的 条评论
为什么被折叠?



