【问题标题】:java I/O blocks thread on server sidejava I/O 阻塞服务器端的线程
【发布时间】:2010-07-08 11:06:53
【问题描述】:

我正在处理客户端套接字连接。客户端是一个GPRS硬件设备。我在我的 serversocket 上接收来自这个客户端的请求,然后打开多个线程。我的问题是,当设备/客户端关闭套接字时,我的 IO 检测到会引发异常,但是当我在将请求发送到 serversocket 时从设备中关闭电池时,它会被阻止而不会引发任何异常。有人建议我使用 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 秒后关闭主套接字并停止接收数据。并且发生读取超时错误。

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

提前致谢

**

@斯蒂芬

** 好的,斯蒂芬明白你想说的......你的陈述是正确的“Well yes ... that's what you told it to do.”可能是我无法让你理解我的问题,或者我没有得到 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 应该给出异常并从读取中出来而不影响其他客户端套接字对象(或线程)。

现在我希望我已经把我的困惑和问题告诉了你。

请帮帮我,非常感谢。

【问题讨论】:

  • 你昨天已经问过同样的问题了,你为什么不直接编辑你原来的问题呢? stackoverflow.com/questions/3020248/…
  • 你是说一个线程中的套接字超时会导致从不同套接字读取的无关线程抛出异常?如果是这样,那你怎么知道?会不会是所有线程的套接字读取都超时了?
  • 是的,我也写过“事实上,任何新的客户端连接都会产生相同的错误,服务器应用程序停止接收任何读取数据。”这是任何新客户端在 serversocket 上命中的问题,实际上服务器会立即停止读取,从而为新连接的任何新数据提供 readtimeout 错误。

标签: java


【解决方案1】:

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

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

正如我在回答您上一个问题时所说的那样,您无法区分这些情况:

  • 客户端一段时间内没有数据要发送。
  • 网络分区一段时间。
  • 客户端已从网络中消失。

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

编辑

NIO 无济于事。当我在上面说“不能”时......我的意思是物理上不可能做到这一点。这是一个类比,可以帮助您理解。

Outer 之间的唯一通信 WoopWoop 和世界其他地方是 通过信。每周一次,我的朋友在 外 WoopWoop(独居)帖子 给我的一封信,让我填写 闲话。上周我没有收到 我朋友的来信。我如何判断:

  1. 我的朋友死了,
  2. 我的朋友上周没有八卦,
  3. Outer WoopWoop 邮政工人罢工,或
  4. 以上所有?

正确的答案是我不知道。

【讨论】:

  • 感谢您的回复斯蒂芬。我读到了关于 nio .. 它可以成为我的解决方案吗?使用它有什么优点和缺点?如果是的话,你能分享一个使用 nio 的示例代码吗?提前致谢。
猜你喜欢
  • 2014-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
相关资源
最近更新 更多