在 C 语言中,调用 socket
的 connect
函数可能会发生阻塞的情况有多种原因,下面列举了一些常见的原因:
-
网络延迟: 如果网络延迟较大,可能会导致
connect
函数阻塞等待连接成功。特别是在连接远程服务器时,网络延迟可能会增加连接的等待时间。 -
目标主机不可达: 如果目标主机不可达或者网络中存在问题,
connect
函数可能会一直阻塞等待连接结果。这种情况可能是由于网络故障、防火墙设置等原因造成的。 -
目标主机端口未监听: 如果目标主机端口未处于监听状态,
connect
函数会一直等待连接结果,导致阻塞。在这种情况下,连接会一直处于等待状态,直到目标主机端口开始监听连接。 -
连接队列已满: 当服务器端的连接队列已满时,
connect
函数会阻塞。在这种情况下,服务器无法接受新的连接请求,导致客户端的connect
函数阻塞等待。 -
防火墙或网络设备限制: 防火墙、路由器或其他网络设备的设置可能会导致连接阻塞。这些设备可能会对连接进行筛选、限制或延迟,从而导致连接阻塞。
-
操作系统限制: 操作系统对网络连接数、超时时间等方面可能有限制,这些限制也可能导致
connect
函数阻塞。
在处理 connect
函数阻塞的情况时,可以考虑设置连接超时时间、处理网络异常、优化网络通信等方法来减少阻塞时间,提高程序的健壮性和性能。
作为 client 端 ,对于 if ((errno != ECONNREFUSED) && (errno != ETIMEDOUT) && (errno != EHOSTUNREACH))
这几个错误 可以尝试 retry connect
int CreateClientSocket(const char *remoteIp, const uint16_t port)
{
int sockfd = -1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
CPCC_ERROR("sock create fail, err=%d.", errno);
return -1;
}
struct sockaddr_in server;
memset(&server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(remoteIp);
int retryCnt = 1;
uint32_t timeInter = 1;
int res = -1;
while (1) {
res = connect(sockfd, (struct sockaddr*)&server, sizeof(server));
if (res == -1) {
if ((errno != ECONNREFUSED) && (errno != ETIMEDOUT) && (errno != EHOSTUNREACH)) {
close(sockfd);
CPCC_ERROR("sock connect fail, err=%d.", errno);
return -1;
} else {
CPCC_INFO("Retry %{public}d connect outside server, sleep %u", retryCnt, timeInter);
sleep(timeInter);
}
timeInter += 1;
retryCnt++;
} else {
break;
}
if (retryCnt > CLIENT_CONNECT_RETRY_TIMES) {
CPCC_ERROR("Retry %{public}d connect server failed.", retryCnt);
return -1;
}
}
return sockfd;
}