我的服务器程序(套接字流)正在运行并且它接受客户端。由于某些异常情况,服务器正在终止。另一端客户端正在等待服务器回复。如何将正在运行的客户端重新连接到新服务器?套接字中的任何功能?
5 回答
connect()
曾经被编辑过的套接字不能被另一个调用重用connect()
。
连接到 TCP 服务器并读取/写入一些数据的步骤如下(伪代码):
sd = socket(...) // create socket descriptor (allocate socket resource)
connect(sd, server-address, ...) // connect to server
read/write(sd, data) // read from server
close(sd) // close /socket descriptor (free socket resource)
如果服务器在connect
所有客户端可以并且应该做的事情之后关闭
close(sd) // close socket descriptor (free socket resource)
然后从头开始:
sd = socket(...) // create socket descriptor (allocate socket resource)
...
从头开始:
connect(sd, server-address, ...) // connect to server
...
可能会导致未定义的行为,但至少会导致错误。
首先让我说一切皆有可能。有一个功能可以为您做到这一点。它与connect
您可能用于 TCP 客户端的相同。您只需要考虑何时需要再次调用此连接。
那么我现在什么时候使用该connect
功能呢?
让我提出一种可能的解决方案。
您需要有某种监视软件(可能是守护程序)来跟踪服务器进程的状态。比如说,它可以定期戳服务器进程以查看它是否还活着。
考虑单个客户端和服务器的情况。客户端在系统 A 上运行;服务器,在系统 B 上。
recv
假设服务器在它编辑任何东西之前已经运行并崩溃了。这意味着客户端将成功连接到服务器并且send
它将失败。当send
失败时,您可以联系系统 B 上的监控软件以查看发生了什么。
如果监控软件报告它没有发现服务器有任何问题,那么就会出现其他问题(可能是中断,你的 NIC 坏了,等等)。这些原因不在本文讨论范围之内。
如果你的监控软件回复说它发现服务器程序死了,那么你可以:
- 回复监控软件要求重新启动服务器
- 或者告诉它自己关闭
- 或者做一些你认为合适的事情。
现在,在系统 A 的客户端中,再次开始socket
, connect
, send
,recv
等的过程。
本质上,您正在创建另一个服务器 X,它负责您当前的服务器 Y。当服务器 Y 死机时,您会寻找服务器 X 的原因。
int
connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)
{
int nsec;
/*
* Try to connect with exponential backoff.
*/
for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) {
if (connect(sockfd, addr, alen) == 0) {
/*
* Connection accepted.
*/
return(0);
}
/*
* Delay before trying again.
*/
if (nsec <= MAXSLEEP/2)
sleep(nsec);
}
return(-1);
}
由 unix Environment 书中的 Advanced Programming 引用。
您还可以使用:
SO_REUSEADDR
在setsockopt()
. 它允许重用本地地址。
您连接到新服务器的方式与连接到原始服务器的方式相同。对此没有不同的 API。我不明白你为什么会有其他想法..
您无法在服务器中处理此问题,但您可以为您的客户端创建一个会话,然后当您的客户端重新连接时恢复其设置并继续发送和接收消息,并在您的客户端应用程序中创建一个具有特定间隔的线程以检查服务器是否可用与否,如果是这样,请尝试重新连接程序,但是,我建议您检查您的服务器端程序,您的程序出现故障会发生什么?