linux connect网络连接检测

三次握手同时做其他的处理。connect要花一个往返时间完成,从几毫秒的局域网到几百毫秒或几秒的广域网。这段时间可能有一些其他的处理要执行,比如数据准备,预处理等。


建立connect连接,此时socket设置为非阻塞,connect调用后,无论连接是否建立立即返回-1,同时将errno(包含errno.h就可以直接使用)设置为EINPROGRESS, 表示此时tcp三次握手仍旧进行,如果errno不是EINPROGRESS,则说明连接错误,程序结束。 


当客户端和服务器端在同一台主机上的时候,connect回马上结束,并返回0,有时候也会返回-1; 当客户端与服务器不在同一主机上,一般情况都会返回-1;

 所以需要使用select机制来检测connect是否已经连接上服务器;

注:需要设置为非阻塞模式

void setnonblocking(int sock) 
{     
int opts;     
opts = fcntl(sock,F_GETFL);     
if (opts < 0)     
{         
exit(1);     
}     
opts = opts|O_NONBLOCK;     
if (fcntl(sock, F_SETFL, opts) < 0)     
{         
exit(1);        
}   
}

int connect2server(char *server,int port)
{
struct sockaddr_in dest;
fd_set fdr, fdw;
struct timeval timeout;
int res;

bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
if (inet_aton(server, (struct in_addr *) &dest.sin_addr.s_addr) == 0)
{
printf ("addr Socket disconnect !!!!!\n");
}


if(connect(g_sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0) {
        if(errno != EINPROGRESS) { // EINPROGRESS 


            perror("Network test...\n");
            close(g_sockfd);
            return -1;
        }
    }
    else {
        printf("Connected\n");
        return 0;
    }


    FD_ZERO(&fdr);
    FD_ZERO(&fdw);
    FD_SET(g_sockfd, &fdr);
    FD_SET(g_sockfd, &fdw);


    timeout.tv_sec = 10;
    timeout.tv_usec = 0;


    res = select(g_sockfd + 1, &fdr, &fdw, NULL, &timeout);
    if(res < 0) {
        perror("Network test...\n");
        close(g_sockfd);
        return -1;
    }
    if(res == 0) {
        printf("Connect server timeout");
        close(g_sockfd);
        return -1;
    }
    if(res == 1) {
        if(FD_ISSET(g_sockfd, &fdw))
        {
            printf("Connected ok\n");
            close(g_sockfd);
            return 0;
        }


    }
    /* Not necessary */
    if(res == 2) {
        printf("Connect server timeout");
        close(g_sockfd);
        return -1;
    }
return -1;
}

你可能感兴趣的:(网络协议)