linux api笔记(2) 网络编程(一)如何判断非阻塞套接字是否连接成功
2010-04-18 19:05
519 查看
在socket编程中,我们往往要设置某个套接字为非阻塞状态;当一个套接字被设置为非阻塞状态之后再进行连接的时候,我们往往不确定其能在什么时候连接成功。
connect函数调用之后返回值非零并且errno的值往往是EINPROGRESS(在某些情况下比如连接本地的对端套接字说不定返回是0,这个目前没确定好)。这就意味着我们需要不断地对这个套接字进行检查。
检查就意味着我们在某个循环里面每次会判断一次套接字的状态,下面先给出比较笨的方法:
上面这种方法需要注意的地方:
1)recv函数的MSG_PEEK参数,这个参数设置之后recv函数从socket的缓冲区中读出数据之后并不会将读取的数据从该缓冲区中删除
2)linux的程序进程会受到信号的干扰,如果一个系统调用后errno为EINTR的时候一般都是因为这个调用的过程中被信号中断了,而一般的
处理方法也是重新执行这个调用,不能将其视为错误情况。
另外还有一种优雅的方法是将这个套接字放到一个I/O模型中监视起来,比如select或epoll模型,一般只需要为其注册可写事件即可,但这不一定,所以就好是可读可写事件都注册好,当其中某个事件发生的时候,我们还是需要和上面一样用recv来判断连接是否成功。
注:其实在收到“可读事件”或“可写事件”时还有一种方法用来判断连接是否成功,那就是
上面的语句执行成功之后(返回值-1表示失败)之后我们应该判断一下error,如果error为非0,那么连接失败,否则成功。
不过需要注意的是,这种方法在windows中不见得有效。
connect函数调用之后返回值非零并且errno的值往往是EINPROGRESS(在某些情况下比如连接本地的对端套接字说不定返回是0,这个目前没确定好)。这就意味着我们需要不断地对这个套接字进行检查。
检查就意味着我们在某个循环里面每次会判断一次套接字的状态,下面先给出比较笨的方法:
while(1) { int ret = recv(sock, buf, 1, MSG_PEEK); if (0 < ret) { //connect success } else if(EAGIN == errno) { //connect success } else if (EINTR == errno) { //signal! ignore it } else if (0 == errno){ //peer close } else { //error } MicroSleep(1000); }
上面这种方法需要注意的地方:
1)recv函数的MSG_PEEK参数,这个参数设置之后recv函数从socket的缓冲区中读出数据之后并不会将读取的数据从该缓冲区中删除
2)linux的程序进程会受到信号的干扰,如果一个系统调用后errno为EINTR的时候一般都是因为这个调用的过程中被信号中断了,而一般的
处理方法也是重新执行这个调用,不能将其视为错误情况。
另外还有一种优雅的方法是将这个套接字放到一个I/O模型中监视起来,比如select或epoll模型,一般只需要为其注册可写事件即可,但这不一定,所以就好是可读可写事件都注册好,当其中某个事件发生的时候,我们还是需要和上面一样用recv来判断连接是否成功。
注:其实在收到“可读事件”或“可写事件”时还有一种方法用来判断连接是否成功,那就是
int error = 0; getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, sizeof(int));
上面的语句执行成功之后(返回值-1表示失败)之后我们应该判断一下error,如果error为非0,那么连接失败,否则成功。
不过需要注意的是,这种方法在windows中不见得有效。
相关文章推荐
- soket编程相关(二)如何判断连接状态断开,Linux:C/Socket多路复用select(),阻塞
- 如何判断连接状态断开,Linux:C/Socket多路复用select(),阻塞
- 面试中的soket编程相关(一)(如何判断连接状态断开,Linux:C/Socket多路复用select(),阻塞
- Linux 如何判断哪个网卡是否连接网线
- 关于ODBC API编程中如何判断DSN是否已存在
- java如何判断一个linux下的文件是否为链接文件。
- 如何判断 Linux 服务器是否被***?
- linux python测试连接mssql安装是否成功需要reetds支持
- Linux如何判断自己的服务器是否被入侵
- linux+笔记:linux下判断一个文件或者目录是否存在
- 如何在shell脚本中,判断一个基本命令执行是否成功?
- ADO.NET笔记——使用Command执行增删改操作,通过判断ExecuteNonQuery()返回值检查是否操作成功
- linux bc命令如何判断成功执行
- WindowMobile如何判断网络有没连接和如何判WebService服务器地址是否正确(wifi有无打开)
- 如何在linux下判断web服务是否开启?
- 如何检查Android中的WiFi网络是否连接成功
- 如何判断一个SOCKET连接是否已经断开
- [RK3288][Android6.0] 调试笔记 --- 如何确认声卡是否注册成功
- 『C/C++』C++构造函数无返回值,如何判断对象是否“构造”成功?
- android 判断当前应用是否与服务器连接成功