Java套接字:从服务器到客户端的开放连接

时间:2013-04-15 14:51:29

标签: java sockets tcp netty nio

我遇到以下独特要求的客户端服务器问题: 1.服务器必须打开与已知客户端的N个连接,客户端只能使用这些连接从服务器请求数据。

到目前为止,我尝试执行以下操作但遇到了一些问题:

  1. 在客户端上有一个套接字侦听器,让它将收到的每个连接排入ArrayBlockingQueue。

  2. 客户端应用将使用上述队列中的可用连接从服务器

  3. 请求数据
  4. 我在服务器上为每个套接字创建一个线程(worker),并通过N个工作线程监听数据请求。

  5. 当我等待工作线程中的传入请求(在服务器上)时,我使用InputStream.isAvailable()检查是否有东西等待读取。

  6. 问题:服务器端的工作线程不知道套接字连接是否仍然存在?即使在客户端应用程序上关闭套接字后,它们仍继续侦听请求。

    如果套接字连接仍然存在,如何让服务器感知?

    我在这里采取了正确的方法吗?

    是否有一个框架可以使实施更容易和更好?

4 个答案:

答案 0 :(得分:1)

为什么不反转协议?

  • 您的客户将启动连接
  • 您的服务器将授权他们(仅允许已知客户端)
  • 然后,您的服务器可以接收/推送数据到客户端,并接收确认
  • 如果连接丢失,客户端可以重新启动(服务器可以跟踪已发送给每个客户端的数据,并在重新连接时重新发送丢失的数据)

答案 1 :(得分:1)

您已使用netty标记了该问题。你尝试过使用Netty吗?在任何一种情况下,我都会推荐它。

  • 您的客户端应使用ServerBootstrap / ServerSocketFactory和适当的通道管道。 Netty已经有了一个可以用来代替BlockingQueue的ChannelGroup概念。您的客户端代码可以通过迭代组并删除一个空闲通道(并在完成后将其放回)来找到一个空闲通道。通道组还会自动检测已关闭的通道并将其从自身中删除。
  • 您的服务器将使用ClientBootstrap / ClientSocketFactory和适当的通道管道以及响应客户端请求的处理程序。
  • 将检测到正常的TCP关闭操作,并关闭通道。如果您担心客户端“崩溃”并使另一端处于不稳定状态,Netty会有一个IdleStateHandler可以在一段时间不活动后关闭该通道

答案 2 :(得分:0)

  

问题:服务器端的工作线程不知道套接字连接是否仍然存在?

是的,他们这样做。当客户端关闭连接时,他们将读取EOS。没问题。

  

即使在客户端应用程序上关闭套接字后,他们仍会继续侦听请求。

只有在忽略EOS条件的情况下才能使用。

  

如果套接字连接仍然存在,如何让服务器感知?

如果在阅读时获得EOS,请关闭套接字并停止读取循环。

  

我在这里采取了正确的方法吗?

您的问题描述已回到正面。是客户端创建与服务器的连接,而不是相反。

答案 3 :(得分:0)

  

当我等待工作线程中的传入请求(在服务器上)时,我使用InputStream.isAvailable()来检查是否有东西等待读取。

InputStream.isAvailable()从不告知对等方是否已关闭连接。您必须致电read()以检查连接是否已关闭。

如果您必须使用InputStream.isAvailable(),则必须至少定期向OutputStream写一些内容,然后您将获得一个IOException,表示该连接已关闭({{1例如)。