connectEx判断是否连接成功

connectEx连接检测
本文介绍如何使用connectEx函数配合GetQueuedCompletionStatus及getsockopt来判断TCP连接是否成功。通过在不同编译模式下测试GetQueuedCompletionStatus的返回值,并结合SO_CONNECT_TIME选项来确认连接状态。

connectEx判断是否连接成功

connectEx是根据socket变化判断是否连接成功,通过GetQueuedCompletionStatus函数对socket判断是否发生变化,因此CreateInCompletionPort函数需要写在connectEx函数前面。

如果连接成功或者失败,GetQueuedCompletionStatus函数都会返回一个5,再通过getsockopt判断是否接连成功。

经过测试,在Debug下GetQueuedCompletionStatus函数会返回一个5,但是如果是在Release下的话GetQueuedCompletionStatus函数返回的是0,与设置接收信息的标识符是相同的,但是在接收的时候
GetQueuedCompletionStatus函数的第4个参数返回的数据长度为0的情况下是连接成功或者连接失败(接收到的数据为0的情况下也有可能),不为0就是接收到数据。

所以在判断返回数据长度为0的时候调用getsockopt函数

int optVal;
int optLen = sizeof(int);
int res = getsocketopt(Socket, SOL_SOCKET, SO_CONNECT_TIME, (char*)&optVal, &optLen);

if (optVal = != -1)
	printf("连接成功");
else
	printf("连接失败");

SO_CONNECT_TIME DWORD 返回已连接套接字的秒数。 此套接字选项仅适用于面向连接的协议。

参考https://learn.microsoft.com/zh-cn/windows/win32/api/winsock/nf-winsock-getsockopt?redirectedfrom=MSDN

int bufferevent_socket_connect(struct bufferevent *bev, struct sockaddr *sa, int socklen) { struct bufferevent_private *bufev_p = EVUTIL_UPCAST(bev, struct bufferevent_private, bev); evutil_socket_t fd; int r = 0; int result=-1; int ownfd = 0; _bufferevent_incref_and_lock(bev); if (!bufev_p) goto done; fd = bufferevent_getfd(bev); if (fd < 0) { if (!sa) goto done; fd = socket(sa->sa_family, SOCK_STREAM, 0); if (fd < 0) goto done; if (evutil_make_socket_nonblocking(fd)<0) goto done; ownfd = 1; } if (sa) { #ifdef WIN32 if (bufferevent_async_can_connect(bev)) { bufferevent_setfd(bev, fd); r = bufferevent_async_connect(bev, fd, sa, socklen); if (r < 0) goto freesock; bufev_p->connecting = 1; result = 0; goto done; } else #endif r = evutil_socket_connect(&fd, sa, socklen); if (r < 0) goto freesock; } #ifdef WIN32 /* ConnectEx() isn't always around, even when IOCP is enabled. * Here, we borrow the socket object's write handler to fall back * on a non-blocking connect() when ConnectEx() is unavailable. */ if (BEV_IS_ASYNC(bev)) { event_assign(&bev->ev_write, bev->ev_base, fd, EV_WRITE|EV_PERSIST, bufferevent_writecb, bev); } #endif bufferevent_setfd(bev, fd); if (r == 0) { if (! be_socket_enable(bev, EV_WRITE)) { bufev_p->connecting = 1; result = 0; goto done; } } else if (r == 1) { /* The connect succeeded already. How very BSD of it. */ result = 0; bufev_p->connecting = 1; event_active(&bev->ev_write, EV_WRITE, 1); } else { /* The connect failed already. How very BSD of it. */ bufev_p->connection_refused = 1; bufev_p->connecting = 1; result = 0; event_active(&bev->ev_write, EV_WRITE, 1); } goto done; freesock: _bufferevent_run_eventcb(bev, BEV_EVENT_ERROR); if (ownfd) evutil_closesocket(fd); /* do something about the error? */ done: _bufferevent_decref_and_unlock(bev); return result; } 分析这段代码的逻辑
10-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值