【问题标题】:Java server socket data input stream read timeoutJava服务器socket数据输入流读取超时
【发布时间】:2014-06-16 19:05:39
【问题描述】:

我当时只有一个 java 服务器和一个客户端。

  • 客户端连接并发送卡ID(在服务器端阻塞读取是合适的,因为当时只有1个客户端)
  • 如果卡在数据库中不存在,它只会返回 0 并关闭套接字(没问题)
  • 如果卡确实存在,则返回 1
  • 现在客户端必须向服务器发送 PIN,但必须有一些超时,比如说 10 秒。 在这里我不能使用阻塞读取,我该怎么办? Socket setSoTimeout 不是一个选项,因为第一个读取是阻塞的,但第二个不应该是。

【问题讨论】:

  • 也许你应该考虑线程化。
  • 你能分享一些代码让我们看看你是怎么做的吗?如果您只想让程序在执行特定操作之前等待十秒钟,您可以使用:

标签: java sockets


【解决方案1】:

我的建议是创建一个 ExecutorService 并用它启动一个线程。

这里有一个例子:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html

【讨论】:

    【解决方案2】:

    正确(但不是最简单)的方法是使用java.nio.channels.SocketChannel。这是read 方法读入ByteBuffer。您将它与 java.nio.channels.Selector 结合使用,以从多个套接字中读取而不会阻塞(选择器可帮助您找出哪个有可用数据),但在您的情况下,您可能会对 SocketChannel 感到满意。

    虽然它更难使用 - 没有InputStream,您需要管理ByteBuffer

    另一种方法是启动一个看门狗Thread,它会在超时期间休​​眠,然后在客户端尚未发送 PIN 时关闭Socket。关闭套接字会中断被阻塞的阅读器。

    如果您想这样做,一些较老的问题可以帮助您使用 SocketChannel:

    【讨论】:

    • 如果我错了,请纠正我,但实际上我认为使用 SocketChannel 仍处于阻塞模式。只是您可以检查从多个套接字读取,而不是只等待 1 个套接字。
    • 它仍然处于阻塞模式,但选择器会告诉你什么时候可以不阻塞地阅读。只有当有零字节可供读取时,套接字才会阻塞。
    【解决方案3】:

    服务器应始终使用读取超时。您可以在第一次请求和响应后改变它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-04
      • 2018-09-19
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2014-12-04
      相关资源
      最近更新 更多