【问题标题】:setSoTimeout on a client socket doesn't affect the socket客户端套接字上的 setSoTimeout 不会影响套接字
【发布时间】:2010-11-21 07:46:55
【问题描述】:

我有一个带有三个线程的 Java 应用程序,每个线程打开一个套接字并连接到不同端口上的服务器。 在与服务器建立连接后,我在每个套接字上设置了 so_timeout。 之后,线程阻塞等待 read()。 只有一个线程在 20 秒后超时(这是我设置的超时)。 另外两个忽略超时。 TCP 层是否有可能一次只处理一个超时? 还有其他解释吗?

【问题讨论】:

  • 请发布您的代码,您的问题可能无法捕捉到偷偷摸摸的逻辑错误。
  • 调用 sock.getSoTimeout() 只是为了确保它返回 20000。也发布一些代码。你在什么操作系统上运行?
  • 建立连接的代码如下: while (!connected) { try { client = new Socket(); InetSocketAddress sa = new InetSocketAddress(serverIP, port); client.connect(sa); client.setKeepAlive(true); } catch (UnknownHostException e) { e.printStackTrace();返回空值; } catch (IOException e) { ... } if (client.isConnected()) { // 设置阻塞读取操作的超时时间。试试 {client.setSoTimeout(timeout*1000); } catch (SocketException e) {} 已连接 = true; } }
  • 以及等待读取的代码:try { // Get the input channel in = new BufferedInputStream(clientSocket.getInputStream()); } catch (IOException e) {} while (isActive) { try { bytesRead = in.read(message, 0, BUF_SIZE); } catch (SocketTimeoutException STE) { ... } catch(IOException IOE){ ... } if (bytesRead > 0)processInput(message, 0, bytesRead); }
  • 我确实验证了 so_timeout 已设置。

标签: java sockets timeout


【解决方案1】:

documentation 说:

必须在进入阻塞操作之前启用该选项才能生效。

也许您应该设置它与服务器的连接建立之前,至少在套接字上调用 read() 之前。
但是没有代码很难说...

【讨论】:

    【解决方案2】:

    过去我在处理 Windows 中的 SO_TIMEOUT 时遇到了几个问题。我相信设置它是“应该”设置可能依赖于操作系统并与注册表设置等冲突的底层套接字实现。

    我的建议是不要使用 SO_TIMEOUT 在超时时强制抛出异常。在 read() 之前使用非阻塞 I/O 或检查是否有可用字节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 2015-02-08
      • 2018-05-23
      • 1970-01-01
      • 2012-02-19
      相关资源
      最近更新 更多