0

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

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

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

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

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

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

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

如果套接字连接仍然有效,我怎样才能让我的服务器有意义?

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

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

4

4 回答 4

1

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

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

你为什么不直接反转协议?

  • 您的客户将启动连接
  • 您的服务器将授权它们(仅允许已知客户端)
  • 然后您的服务器可以接收/推送数据到客户端,并接收确认
  • 如果连接丢失,客户端可以重新发起(服务器可以跟踪每个客户端发送了哪些数据,并在重新连接时重新发送丢失的数据)
于 2013-04-15T15:09:25.377 回答
0

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

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

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

于 2013-04-16T08:07:02.330 回答
0

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

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

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

仅当您忽略了 EOS 条件时。

如果套接字连接仍然有效,我怎样才能让我的服务器有意义?

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

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

您的问题描述是从前到后的。是客户端创建与服务器的连接,而不是相反。

于 2013-04-15T22:48:51.623 回答