【问题标题】:client/server socket reconnection客户端/服务器套接字重新连接
【发布时间】:2016-10-20 16:07:16
【问题描述】:

我开发了一个基于套接字的客户端/服务器应用程序。

客户端在 Delphi 中。服务器端在 IBM I (as400) 上

有时,客户端和服务器会断开连接。我不太确定为什么,但我认为这是因为它们之间的一台机器(代理、路由器、防火墙)发送了一个RST 数据包。

无论如何,我正在尝试使用服务器上的相同进程重新连接客户端。 (不是另一个,相同,这很重要)。

为此,我从客户端创建了一个新连接。所以,我在服务器上有两个进程。我将它们称为“LostProcess”和“HelperProcess”。

LostProcess 正在等待数据队列中的数据。

客户端告诉 HelperProcess 它已连接到 LostProcess。

HelperProcess 将数据发送到 LostProcess(通过数据队列)。

HelperProcess 生成一个 giveDescriptor,而 LostProcess 生成一个 takeDescriptor。

然后 HelperProcess 停止,LostProcess 向客户端发送数据(说“我回来了”)。

到目前为止,它可以工作,但是当客户端发送数据时,LostProcess(我们现在可以称之为 RebornProcess)永远不会收到它们(我试图不停止 HelperProcess,并且他是接收数据的人)。

使用 Wireshark,我可以看到客户端使用不同的本地端口发送数据,所以我猜这就是 RebornProcess 没有收到它们的原因。

我试图强制新客户端socket的本地端口和第一个一样,但是然后新客户端socket有一段时间无法连接,如果我等待的时间足够长,我也遇到了和以前一样的问题.

有人知道如何使重新连接工作吗?

【问题讨论】:

  • 除非您说数据已成功发送和接收,除非它是由HelperProcess 接收的,否则我无法理解这个问题。这是有道理的。只要 HelperProcess 继续为数据队列提供服务,那么发送的数据就有可能在此处结束。完全按照设计。

标签: sockets delphi ibm-midrange


【解决方案1】:

您所做的通常是不可能的。一旦 TCP 连接丢失,它就永远消失了。两个应用必须关闭各自的套接字以丢失连接,客户端应用必须创建新的套接字连接以继续与服务器交换数据。

如果客户端应用程序想通过bind()重用同一个本地端口(在大多数情况下通常不建议这样做),但不想等待操作系统先释放端口,那么客户端可以启用在调用bind()connect() 之前,通过setsockopt() 在新套接字上选择SO_REUSEADDR

【讨论】:

  • 我找到了解决方案。丢失的客户端监听一个新的端口,帮助进程告诉客户端在哪个端口上重新连接。
【解决方案2】:

很确定答案是你不能。

如果 TCP/IP 允许新连接重新连接到现有进程连接,则会出现各种安全问题。

您应该终止丢失的进程,而只使用新进程。

【讨论】: