繁体   English   中英

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

[英]Java sockets: open connections from server to client

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

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

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

  2. 客户端应用程序将使用上面队列中可用的连接来从服务器请求数据

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

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

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

如果套接字连接仍然存在,如何让我的服务器感觉到?

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

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

你为什么不反转协议?

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

您已使用netty标记了该问题。 你尝试过使用Netty吗? 无论哪种情况,我都会推荐它。

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

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

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

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

只有你忽略了EOS条件。

如果套接字连接仍然存在,如何让我的服务器感觉到?

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

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

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

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

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

如果必须使用InputStream.isAvailable() ,则必须至少定期向OutputStream写入内容,然后您将获得一个IOException ,指示连接已关闭(例如, connection reset by peer )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM