JAVA中Sockets长连接时使用read()阻塞的问题!急救!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA中Sockets长连接时使用read()阻塞的问题!急救!相关的知识,希望对你有一定的参考价值。

这个问题纠结了我一下午,怎么也没有解决。希望谁能帮帮我!
就是从服务端接收数据,客户端向服务度发送数据,然后服务端返回一条语句可以正常接收;
代码:
byte[] buf = new byte[512];
inputStream.read(buf);
但当服务端在一定时间内返回多条数据时,如服务端处理客户端发来的数据,处理2s后发送返回给客户端,inputStream.read(buf);直接阻塞无响应了。查了很多方法,比如写入一个循环中和单独的线程中。仍然无法实现。如:
while (inputStream.read() != -1)
int len = inputStream.read(buf);

但无论怎样,只要执行inputStream.read(),就会卡死,阻塞无响应。。
这到底是怎么回事。。求解。。搞了一下午了,我真想屎。。谁来救救我!!

参考技术A while (true)
try
byte buff[] = new byte[500];// 缓冲数组
if (buff != null && buff.length > 0)
DataIn.read(buff);
String str = new String(buff);// 接受客户端发送的数据包
String dataBag="客户端\t" + sdf.format(dt) + "\n";


if(stopFlag)
break;
catch (IOException ioe)
System.out.println("读写异常:"+ioe.getMessage());


我的代码,运行正常,看到了吗?只要把buff[]转成字符串就完事了追问

非常感谢帮忙。
就是在.read(buff);的时候还是阻塞了。。。直接无响应。。。然后也没有异常报错提示。。
这是怎么回事呢?服务端那边是正常的,检测有数据返回,但就是接收不到。。

参考技术B 楼主代码有一定问题
byte[] buf = new byte[512];
int n=0;
while( (n=inputStream.read(buf)) != -1 )
//处理buf里的数据
追问

还是那个问题,inputStream.read(buf),

执行到read()就会卡死。。。到底是怎么一回事。。。

追答

把2端的源代码贴出来看看

使用 java-sockets 进行长轮询

【中文标题】使用 java-sockets 进行长轮询【英文标题】:long polling using java-sockets 【发布时间】:2015-08-06 08:04:56 【问题描述】:

我开发了一个基于 Java 的客户端,它使用 Java 套接字连接到服务器。对于信息交换,我使用了 http-Protocol。基本上,我通过套接字建立连接,并在客户端编写了一个向服务器发出 http 请求的方法。我要连接的服务器是我自己开发的一个非常简单的服务器。我想问一下,是否可以通过套接字使用请求方法进行长轮询。

由于我的班级客户端中有一个请求方法,我有两个选项: 连续请求: 包括每毫秒发送一个请求,询问是否发生了新事件。 长时间请求(称为长轮询):客户端发送请求。如果有响应,服务器将回答。否则它不会发送响应并且请求将超时。这时客户端发送一个新的请求

这是我的模型的描述:

I wrote a simple http-client and a simple http-server. 
*The client has a method request 
* the server has a method respond.
*The client send a get-request by using its request-method to my server (gives back a command to the client)
**That server reponds to this request using its respond-method.  

如何扩展我的程序? 如何使用可用的客户端和服务器实现长轮询?

【问题讨论】:

定义“长轮询”。您受到 HTTP 语义的限制。不清楚你在问什么。 我已经编写了一个客户端-服务器模型:一个客户端和一个服务器。所以我写了一个简单的http-client和一个简单的http-server。客户端有一个方法请求,服务器有一个方法响应。客户端通过使用它的方法请求向我的服务器发送一个获取请求,并且该服务器使用它的响应方法响应这个请求。该程序运行良好。如何扩展我的程序。如何使用可用的客户端和服务器实现长轮询? 长轮询是什么意思? 任何代码?你为什么要自己实现一个http服务器?例如,JDK 本身甚至包含一个。你使用异步 IO 吗?如果客户端数量增长并超过某个限制,那么长时间轮询可能会杀死您的 VM。 我正在使用 java 模拟嵌入在设备中的 http-server。所以我不需要复杂的http-requets。对于 IO,我使用的是 java.io 的标准类。我应该使用循环并将请求方法放入其中吗? 【参考方案1】:

我会说,对于一个简单的解决方案(性能等撇开),您不需要做太多事情:您正在从服务器请求“事件”。服务器在循环中接受请求并将每个请求的处理委托给不同的线程(参见 java.util.concurrent.ExecutorService)。每个处理线程都会等待,直到有事件可用(您可以使用 java.util.concurrent.BlockingQueue)并响应请求。如果配置了超时(参见 Socket.setSoTimeout,有可能根本没有超时)并且超时已过(抛出 java.net.SocketTimeoutException),客户端可以关闭现有连接并再次连接。

出于稳定性原因,我会设置一些(长)超时,否则可能无法识别断开的连接。

如果您有很多客户端,请考虑在服务器上使用非阻塞 IO。使用传统的 ServerSocket,每个客户端都会阻塞一个线程。如果这不是问题,请坚持使用 ServerSocket,因为它不那么复杂且更直观。

如果您不想重新发明***,请查看Jetty 或类似的 HTTP 部分库。您仍然可以拥有相同的结构,但您会得到一个不错的HttpRequest,而不是普通的二进制流。

【讨论】:

以上是关于JAVA中Sockets长连接时使用read()阻塞的问题!急救!的主要内容,如果未能解决你的问题,请参考以下文章

Java IPC w/Sockets - 使用环回设备

websocket长连接

WebSocket 长连接

Java:这两种设置Socket超时时间的方法有啥不同吗?

java socket长连接,在本地测试一切正常,放到服务器上出现乱码!但是发送的数据中没有中文。

使用 Sockets 发送和接收数据