accpet和connect設置超時


三次握手

TCP連接建立的開始是三次握手,通過三次交互確認連接成功,在客戶端調用connect時,客戶端發送sync消息給服務端,服務端收到sync消息后,返回一個ack+sync,並等待ack,客戶端收到ack+sync后,返回一個ack,connect返回,服務端收到ack后,accept返回,如下圖所示:

 


connect超時設置

如果connect連接的服務端不存在,或是異常了,會出現什么情況,可能有以下幾種情況:

  • 服務端返回連接錯誤

  • 等待系統默認的75秒超時

上述兩種情況都是不可控的,因此可以通過設置超時時間的方式控制超時時間,有下述兩種方法。

非阻塞connect+select

將conenct設置成非阻塞后,connect在發送sync后直接返回-1,然后使用select等待ack+sync,select是可以設置超時時間,因此達到設置超時時間的目的。注意需要將socket恢復成阻塞模式,如下所示:

dwSign = 1;
if((err = ioctl(socket, FIONBIO, &dwSign)) < 0)
{
    printf("ioctl socket failed, errno = %d!\n", err);  
    close(socket);
    return err;
}

SOCKADDR_IN tServerAddrInfo = {0};
tServerAddrInfo.sin_family       = AF_INET;
tServerAddrInfo.sin_addr.s_addr  = ServerIP;
tServerAddrInfo.sin_port         = ServerPort;
int bRet = 0x0;
fd_set set = {0x0};
if(-1 == connect(socket, (SOCKADDR*)&tServerAddrInfo, sizeof(SOCKADDR)))
{
    tm.tv_sec = 10;
    tm.tv_usec = 0;
    FD_ZERO(&set);
    FD_SET(socket, &set);
    
    // select返回值大於0,表示有數據可以操作;select返回值等於0,表示超時
    if(select(socket + 1, NULL, &set, NULL, &tm) > 0)
    {
        // 獲取socket的error值,0表示成功
        getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
        if(error == 0)
        {
            bRet = TRUE;
        }
        else
        {
            bRet = FALSE;
        }
    }
    else
    {
        bRet = FALSE;
    }
}
else
{
    bRet = TRUE;
}

dwSign = 0;
if(0 > (err = ioctl(socket, FIONBIO, &dwSign)))
{
    printf("ioctl socket failed, errno = %d!\n", err);  
    close(dwSocket);    
    return err;
}

 設置socket的發送超時時間

調用connect函數實際上是發送sync報文,如果設置發送超時時間,那么也就可以實現connect的超時時間,如下所示:

struct timeval timeout = {10, 0);
setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));

 


accpet超時設置

既然可以通過設置發送超時時間,控制connect的超時時間,那么同理,也可以通過設置接收超時時間來設置accept的超時時間,如下所示:

struct timeval timeout = {10, 0};
setsockopt(proxy_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM