非阻塞connect和accept

2018-04-17  本文已影响436人  小怪兽狂殴奥特曼

1 非阻塞connect

1.1 阻塞模式与非阻塞

调用connect会发起三次连接。

阻塞模式下,connect的返回结果:

非阻塞模式下,调用connect后会立刻返回EINPROGRESS,同时三次握手还在进行。

1.2 非阻塞模式的实现

int socfd = socket();
//set non-blocking
int ret = connect(sockfd, ...);
if(ret < 0)
{
    return -1;
}
if(errno == EINPRPGRESS)
{
    fd_set rdset, wrset;
    FD_SET(sockfd, rdset);
    FD_SET(sockfd, wrset);
    ret = select(sockfd+1, &rdset, &wrset, NULL, timeout);
    if(FD_ISSET(sockfd, &wrset))
    {
        if(FD_ISSET(sockfd, rdset))
        {
            //清楚sock error
        }
        //成功连接
        return sockfd.
    }
}

1.3 非阻塞connect的意义

非阻塞connect的意义在于提高并发度。阻塞connect下,完成一个三次握手需要耗费一个RTT时间。RTT时间波动很大。从局域网内的几时毫秒到广域网的几十秒。阻塞模式下,进程被connect阻塞住,什么都干不了。非阻塞下,我们可以让select或者epoll来监听listenfd,直到完成三次连接再继续进行数据的手法。

2 非阻塞accept

2.1 非阻塞accept的实现

int sockfd = socket();
//set non-blocking
bind()
fd_set rdset;
FD_SET(sockfd, &rdset);
while(1)
{
    int ret = select(sockfd+1, &rdset, NULL, NULL, timeout);
    if(ret < 0)
    {
        // err log
    }
    if(errno == EPROTO || ...)
    {
        continue;
    }
    int accept(sockfd,...);
}

2.2 注意点

完成三次连接后,accept之前,select为可读,这个时候如果对端关闭连接,accept这个关闭的sockfd会阻塞。

所以select返回后,accept前,总是忽略EWOULDBLOCK和ECONNABORTED、EPROTO、EINTR。

2.3 非阻塞accept的意义

非阻塞accept的意义同样在于提高并发度。

上一篇 下一篇

猜你喜欢

热点阅读