accept與connect的超時設置

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

相關文章
相關標籤/搜索