connect会阻塞,怎么解决?如果select返回可读,结果只读到0字节,什么情况?

步骤1: 设置非阻塞,启动连接

实现非阻塞 connect ,首先把 sockfd 设置成非阻塞的。这样调用

connect 可以立刻返回,根据返回值和 errno 处理三种情况:

(1) 如果返回 0,表示 connect 成功。

(2) 如果返回值小于 0, errno 为 EINPROGRESS,  表示连接

      建立已经启动但是尚未完成。这是期望的结果,不是真正的错误。

(3) 如果返回值小于0,errno 不是 EINPROGRESS,则连接出错了。

步骤2:判断可读和可写

然后把 sockfd 加入 select 的读写监听集合,通过 select 判断 sockfd

是否可写,

(1) 如果连接建立好了,,那么 sockfd 是可写的

(2) 如果连接发生错误,sockfd 也是可读和可写的。

步骤3:使用 getsockopt 函数检查错误

getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &len)

在 sockfd 都是可读和可写的情况下,我们使用 getsockopt 来检查连接

是否出错。但这里有一个可移植性的问题。

如果发生错误,getsockopt 源自 Berkeley 的实现将在变量 err 中

返回错误,getsockopt 本身返回0;(centos是这种错误)

然而 Solaris 却让 getsockopt 返回 -1,

并把错误保存在 errno 变量中。所以在判断是否有错误的时候,要处理

这两种情况。

步骤4:重新将套接字设置为阻塞

如果select返回可读,结果只读到0字节,什么情况?

某个套接字集合中没有准备好,可能会select内存用FD_CLR清该位为0

猜你喜欢

转载自blog.csdn.net/single6/article/details/81363474