Socket
客户端connect 服务器时候,有可能服务器down掉了,从而导致一直在等connect超时,这个系统时间是21秒左右。我试着用setsockopt去设置connect超时时间,不行 不管用。
timeval t{3, 1};
ret = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
ret = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t));
ret = ::connect(socket, (sockaddr *) &addr, sizeof(addr));
查阅资料,有人提出把socket设为非阻塞然后可以用select限制超时时间
我尝试在linux上测试一下如下,发现确实可以提前Connet TimeOut的时间。
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <cstring>
#include <cstdio>
#include <errno.h>
int main()
{
sockaddr_in addr{};
int socket = ::socket(AF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(9999);
int error = 0, ret = 0;
char *retStr = nullptr;
timeval t{3, 0};
auto set_block = [](int fd, bool block)
{
int b = block ? 1 : 0;
ioctl(fd, FIONBIO, &b);
};
set_block(socket, 0);
ret = ::connect(socket, (sockaddr *)&addr, sizeof(addr));
if (ret == -1)
{
fd_set set;
FD_ZERO(&set);
FD_SET(socket, &set);
if (select(socket + 1, nullptr, &set, nullptr, &t) > 0)
{
socklen_t len = sizeof(error);
getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);
if (error != 0)
{
retStr = ::strerror(error);
printf(retStr);
goto ERROR_SOCKET;
}
}
else
{
ERROR_SOCKET:
//TIMEOUT, set BLOCK
set_block(socket, 1);
close(socket);
}
}
return 0;
}