gpt4 book ai didi

Java I/O 在服务器端阻塞线程

转载 作者:行者123 更新时间:2023-11-29 09:25:01 25 4
gpt4 key购买 nike

我正在处理客户端套接字连接。 client是一个GPRS硬件设备。我在我的服务器套接字上收到来自该客户端的请求,然后打开多个线程。我的问题是,当设备/客户端关闭套接字时,我的 IO 检测到会引发异常,但是当我在将请求发送到服务器套接字时关闭设备的电池时,它会被阻止而不会引发任何异常。有人建议我使用 setSOTimeout() 从阻塞线程中退出。

我试过 Socket.setSOTimeout(int) 。但这对我来说是行不通的。我正在正确发送我的代码。

//  inside main class--- 

public class ServerSocketClass{
public ServerSocketClass() {
try{
serverSocket = new ServerSocket(port);//creating a serversokcet on a port
System.out.println("Server waiting for client on port " +
serverSocket.getLocalPort());
} catch (Exception e) {
e.printStackTrace();
handleExceptions("errorServerSocketOpen.txt", e);
System.exit(0);
}
try {
while (true) {
Socket clientSocket = serverSocket.accept();//accepting the client connection and //creating client socket

new AcceptConnection(clientSocket);//calling the constructor of other //class to open a new thread
System.out.println("constructor called.....");
}
} catch (Exception e) {
handleExceptions("errorClientSocketOpen.txt", e);
}
}
}
//inside other class---


public class AcceptConnection implements Runnable {
public AcceptConnection(Socket socket) {
this.clientSocket = socket;
if (clientSocket != null) {
new Thread(this).start();
}
public void run() {
// clientSocket.setSoTimeout(60000);// this is what i added.timeout on each client socket opened in threads
InputStream inputStream = clientSocket.getInputStream();
DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
byte[] mainBuffer = new byte[2048];
int len = -1, totalLength = 0;
debugInfo = " GOING TO READ FROM SOCKET.... " + "\n";
while ((len = inputStream.read(mainBuffer)) > -1) {
totalLength = len;
}//end of while
} }//end of other class

现在我的问题是,当打开多个线程并且我从客户端发送数据时,60 秒后它关闭主套接字并停止接收数据。并且发生读取超时错误。

请帮助我并告诉我如何实现我的目标。

提前致谢

**

@stephen

**好吧,史蒂芬明白了你想说的……你的陈述是正确的“嗯,是的......这就是你告诉它要做的。”可能是我无法让你理解我的问题或者我没有得到 setSoTimeout() 逻辑,因为我是 Java 新手。我想再问一次...这就是我为每个客户端连接创建新客户端套接字并为每个客户端连接打开新线程的方式。

    while (true) {
Socket clientSocket = serverSocket.accept();//accepting the client connection and //creating client socket
new AcceptConnection(clientSocket);//calling the constructor of other class to open a new thread
System.out.println("constructor called.....");
}
public void run() {
// clientSocket.setSoTimeout(60000);// this is what i added.timeout on each uclient socket opened in threads
........................................
.......................................
}

现在我想说的是,如果我为新的客户端连接打开一个新线程,并且我将 setSoTimeout() 分别放在每个客户端连接对象上,那么如果特定线程 A 在读取时在 I/O 上被阻塞,那么在设置超时后在 setSoTimeout(50000) 中,比如 50 秒,只有线程 A 应该退出读取并给出异常,而不是同时运行的其他线程说 B、C、D。但在我的情况下,超时后所有线程在给出异常后返回并在事实上,任何新的客户端连接都会出现相同的错误,并且服务器应用程序会停止接收任何读取的数据。我只希望线程 A 应该给出异常并从读取中退出而不影响其他客户端套接字对象(或线程)。

现在我希望我已经告诉你关于我的困惑和问题的一切。

请帮助我,非常感谢。

最佳答案

now my problem is that when multiple threads are opened and i send the data from client than after 60 seconds it closes the main socket and stops receiving the data.and a readtimeout error occurs.

嗯,是的......这就是你告诉它要做的。

正如我在回答您之前的问题时所说,您无法区分这些情况:

  • 客户端在一段时间内没有数据可发送。
  • 网络被分割了一段时间。
  • 客户端已从网络中消失。

您的另一个选择是调用 Socket.setKeepAlive()启用 TCP keepalives .这会导致定期执行特殊的“keepalive”握手,以确保 TCP/IP 连接仍然有效。遗憾的是,您似乎无法在 Java 中设置 TCP/IP 保活间隔。

编辑

NIO 不会提供帮助。当我在上面说“不能”时……我的意思是物理上不可能这样做。这里有一个类比可以帮助您理解。

The only communication between Outer WoopWoop and the rest of the world is by letter. Once a week my friend in Outer WoopWoop (who lives alone) posts a letter to me to fill me in on the gossip. Last week I didn't receive a letter from my friend. How can I tell if:

  1. my friend has died,
  2. my friend had no gossip last week,
  3. the Outer WoopWoop postal workers have been on strike, or
  4. all of the above?

正确答案是我不知道。

关于Java I/O 在服务器端阻塞线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3202908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com