异步连接和断开与 epoll (Linux) [英] Async connect and disconnect with epoll (Linux)

查看:34
本文介绍了异步连接和断开与 epoll (Linux)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 epoll for Linux 为 tcp 客户端异步连接和断开连接.有分机.Windows 中的函数,例如 ConnectEx、DisconnectEx、AcceptEx 等...在 tcp 服务器标准接受功能正在工作,但在 tcp 客户端不工作连接和断开...所有套接字都是非阻塞的.

I need async connect and disconnect for tcp client using epoll for Linux. There are ext. functions in Windows, such as ConnectEx, DisconnectEx, AcceptEx, etc... In tcp server standard accept function is working, but in tcp client doesn't working connect and disconnect... All sockets are nonblocking.

我该怎么做?

谢谢!

推荐答案

要做一个非阻塞的 connect(),假设套接字已经被设置为非阻塞:

To do a non-blocking connect(), assuming the socket has already been made non-blocking:

int res = connect(fd, ...);
if (res < 0 && errno != EINPROGRESS) {
    // error, fail somehow, close socket
    return;
}

if (res == 0) {
    // connection has succeeded immediately
} else {
    // connection attempt is in progress
}

对于第二种情况,connect() 因 EINPROGRESS 失败(并且仅在这种情况下),您必须等待套接字可写,例如for epoll 指定您正在此套接字上等待 EPOLLOUT.一旦你得到通知它是可写的(使用 epoll, 期望得到一个 EPOLLERR 或 EPOLLHUP 事件),检查连接尝试的结果:

For the second case, where connect() failed with EINPROGRESS (and only in this case), you have to wait for the socket to be writable, e.g. for epoll specify that you're waiting for EPOLLOUT on this socket. Once you get notified that it's writable (with epoll, also expect to get an EPOLLERR or EPOLLHUP event), check the result of the connection attempt:

int result;
socklen_t result_len = sizeof(result);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0) {
    // error, fail somehow, close socket
    return;
}

if (result != 0) {
    // connection failed; error code is in 'result'
    return;
}

// socket is ready for read()/write()

根据我的经验,在 Linux 上,connect() 永远不会立即成功,您总是需要等待可写性.但是,例如,在 FreeBSD 上,我已经看到非阻塞 connect() 到 localhost 立即成功.

In my experience, on Linux, connect() never immediately succeeds and you always have to wait for writability. However, for example, on FreeBSD, I've seen non-blocking connect() to localhost succeeding right away.

这篇关于异步连接和断开与 epoll (Linux)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆