connect超時:服務器
咱們都知道,connect對應與三次握手中的第一次發送SYN,而對待服務器的ACK,若是服務器沒有啓動服務器,有些機器會馬上返回一個RST表示服務器拒絕,從而connect失敗,但又些服務器爲了防止攻擊,什麼也不發送,直至客戶端connect超時,而這一時間又75s,對於客戶端來講是不能接收的。因此須要設置connect的超時時間。ui
利用select設置connect的超時時間:spa
<span style="white-space:pre"> </span>uint32_t ul = 1;
ioctl(sock, FIONBIO, &ul);//設置成非阻塞
printf("start time: %u\n", time(0));
bool success = false;
if (connect(sock, (sockaddr *)&srv_addr, sizeof srv_addr ) == -1)
{
<span style="white-space:pre"> </span>struct timeval tm;
tm.tv_sec = 3;
tm.tv_usec = 0;
<span style="white-space:pre"> </span>fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
if (select(sock + 1, NULL, &set, NULL, &tm) > 0)
{
int error = 0;
int len = sizeof(int);
getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
if (0 == error) success = true;
}
else
{
success = false;
}
}
ul = 0;
ioctl(sock, FIONBIO, &ul); //設置成阻塞
accept超時:.net
一半來講服務器應該都是在accept狀態,也就無需設置accept超時時間,但一些特殊狀況仍是須要的。對於accept咱們能夠使用select多路複用來實現超時設置,但那個代碼較多。那有沒有別的辦法呢?咱們指定,accept對應三次握手中中服務器接收SYN,那麼咱們能不能經過設置recv超時來實現accept超時呢?答案是確定的。blog
struct timeval timeout = {6,0};
if (setsockopt(proxy_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)) != 0)
{
printf("set accept timeout failed");
}
sock = ::accept(proxy_sock, (sockaddr *)NULL, NULL);get
既然能夠用recv超時來設置accept超時,那對於connect能不能經過設置send超時來實現connect超時呢?答案是確定的!!!
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));
只要將connect和accept對應到三次握手過程當中就不難理解這些了。
綜上:it
咱們能夠經過設置SO_RECVTIMEO和SO_SENDTIMEO來設置accept超時和connect超時。io
---------------------
做者:繁華落盡夢一場
來源:CSDN
原文:https://blog.csdn.net/zhangqi_gsts/article/details/50269843
版權聲明:本文爲博主原創文章,轉載請附上博文連接!ioc