1、非阻塞connect

在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长的时间,我们在连接之前将socket设置为非阻塞模式之后,调用connect函数之后,立即返回,如果成功返回0,如果不成功则返回EINPROGRESS,这个值表明连接正在进行,我们可以设置一个超时时间,然后在这个时间段内不停的检查socket是否连接上了,如果在这个时间段内还没有连上,则返回失败。在这个检查的过程中我们可以做一些其他事情,而不必等待连接。

实现这个检查过程,有两种方式:一种方法是用一个while循环来做,另一种方法是通过select来做。

方法一:

 if (connect(sockfd, (struct sockaddr *) &address, sizeof(address)) < )
{
err = errno; if (err != EINPROGRESS)
{
socket_ok = -;
}
else
{
while (true) /* is noblocking connect, check it until ok or timeout */
{
connect(sockfd, (struct sockaddr *) &address, sizeof(address)); err = errno;
switch (err)
{
case EISCONN: /* connect ok */
connect_ok = ;
break; case EALREADY: /* is connecting, need to check again */
usleep();
break; default:
connect_ok = -;
break;
} if (connect_ok == )
{
break;
} if (connect_ok == -)
{
break;
} if ( (timeout > ) && ((time(NULL) - begin_time) > timeout) )
{
break;
}
}
}
}
else /* Connect successful immediately */
{
connect_ok = ;
}

方法二:

 int CTCPConn::AsynConnectToServer(timeval tmConnTimeout)
{
int nRet = -; if( m_nEntityID <= )
{
return -;
} if( m_stSocket.CreateClient() )
{
LOG("Conn create client of DBServer %d failed.\n", m_nEntityID);
return -;
} nRet = m_stSocket.AsynConnectTo(m_ulIPAddr, m_unPort); // 返回-1表示正在连接
if ( nRet != - )
{
return nRet;
} fd_set writeSets;
SOCKET iSocketFD = m_stSocket.GetSocketFD();
FD_ZERO(&writeSets);
FD_SET(iSocketFD, &writeSets); nRet = select(iSocketFD + , NULL, &writeSets, NULL, &tmConnTimeout); if ( nRet <= )
{
m_stSocket.Close();
return -;
} if ( !FD_ISSET(iSocketFD, &writeSets) )
{
m_stSocket.Close();
return -;
} #ifdef WIN32
int nLen = sizeof(nRet);
getsockopt(iSocketFD, SOL_SOCKET, SO_ERROR, (char*)&nRet, &nLen);
#else
socklen_t nLen = sizeof(socklen_t);
getsockopt(iSocketFD, SOL_SOCKET, SO_ERROR, (char*)&nRet, &nLen);
#endif if( nRet != )
{
m_stSocket.Close();
return -;
} m_stSocket.SetConnected(); return ;
}

用select函数检查是否可写,这里可以设置一个超时时间,如果连接成功了的话,则socket变为可写的,select函数是可以检测到。检测到可写之后,用getsockopt函数来获取选项值,如果为0,则证明连接成功。

非阻塞连接的用途:

(1)可以在socket进行三次握手的时候干其他事情,不至于阻塞;

(2)可以同时进行多个连接,在web应用中比较常见(本人自己认为,浏览器就用到了这个,但具体怎么做的没有去了解)

(3)可以设置较短的超时时间,一般connect设计的时候都会有一个超时时间,会比较长,设置为非阻塞我们就可以自己来设定超时时间。

2、非阻塞accept

非阻塞accept主要用来解决以下问题:

用select检测socket状态,如果有连接就调用accept,这样如果在select检测到由连接请求,在调用accept之前,这个请求断开了,然后调用accept的时候就会阻塞在哪里,除非这时有另外一个连接请求,如果没有,则一直被阻塞在那里。(本人以为如果把accept单独放在一个线程中,不会出现以上问题,就是不明白这样做有什么坏处)。

UNIX网络编程-非阻塞connect和非阻塞accept的更多相关文章

  1. UNIX网络编程——UDP 的connect函数(改进版)

    上一篇我们提到,除非套接字已连接,否则异步错误是不会返回到UDP套接字的.我们确实可以给UDP套接字调用connect,然而这样做的结果却与TCP连接大相径庭:没有三次握手.内核只是检查是否存在立即可 ...

  2. UNIX网络编程——非阻塞connect:时间获取客户程序

    #include "unp.h" int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) ...

  3. UNIX网络编程——非阻塞connect

    当在一个非阻塞的TCP套接字上调用connect时,connect将立即返回一个EINPROGRESS错误,不过已经发起的TCP三次握手继续进行.我们接着使用select检测这个连接或成功或失败的已建 ...

  4. unix网络编程 str_cli epoll 非阻塞版本

    unix网络编程 str_cli epoll 非阻塞版本 unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io. 可以看到采用非 ...

  5. UNIX网络编程---传输层:TCP、UDP、SCTP(二)

    UNIX网络编程----传输层:TCP.UDP.SCTP 一.概述 本章的焦点是传输层:包括TCP.UDP.和SCTP(流控制传输协议).SCTP是一个较新的协议,最初设计用于跨因特网传输电话信令. ...

  6. UNIX网络编程中的需要注意的问题

    字节流套接字上调用read或write,输入或输出的字节数可能比请求的数量少,这个现象的原因在于内核中用于套接字的缓冲区可能已经达到了极限.此时所需要的是调用者再次调用read或write函数.这个现 ...

  7. 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

    本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...

  8. UNIX网络编程——使用select函数编写客户端和服务器

    首先看原先<UNIX网络编程--并发服务器(TCP)>的代码,服务器代码serv.c: #include<stdio.h> #include<sys/types.h> ...

  9. UNIX网络编程——并发服务器(TCP)

    在迭代服务器中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现. 网络服务器通常用fork来同时 ...

  10. 《Unix 网络编程》08:基本UDP套接字编程

    基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...

随机推荐

  1. Java设计模式(十二) 策略模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...

  2. python3 如何使用ip、爬虫

    使用urllib.request.random模块,不说了贴代码 url="*"; iplist=['70.254.226.206:8080'];proxy_support=url ...

  3. 在项目中导入MRC的文件时解决办法

    1.由于在项目中要使用到第三方框架和其他的类的时候,而它用的是MRC的时候,其最简便的方法:完成从MRC到ARC的转换. 1.点击工程文件,进入到工程的设置里面. 2.看见Build Phases,就 ...

  4. ST第二次作业,相关程序测试及测试用例

    public static int findLast(int[]x,int y){ for(int i = x.length-1;i>0;i--){//i>=0 if(x[i] == y) ...

  5. ul和dl的区别

    列表中有标题的时候就用dl,没有的话就用ul

  6. 差分:IncDec Sequence 差分数组

    突然就提到了这个东西,为了不再出现和去年联赛看见二分没学二分痛拿二等第一的情况,就去学了一下,基础还是比较简单的-- 先看一个经典例题: 给定一个长度为n的数列{a1,a2...an},每次可以选择一 ...

  7. SqlServer阅读收集

    1.根据字段名,查找相关表--INFORMATION_SCHEMA.COLUMNS SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME ...

  8. Ionic开发实战

    转自:http://blog.csdn.net/i348018533/article/details/47258449/ 折磨的两个月!Ionic从零单排,到项目发布!遇到了很多问题但都一一解决了,此 ...

  9. [转] Linux下 config/configure/Configure、make 、make test/make check、sudo make install 的作用

    转自:http://blog.csdn.net/secondjanuary/article/details/8985795 这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装 ...

  10. 让CSS布局更加直观:box-sizing

    让CSS布局更加直观:box-sizing 如果你写过CSS或者你接触过CSS,相信你一定对盒子模型一点都不陌生.CSS其中一个让人比较困惑的地方就在于它的盒子模型中关于高度和宽度的计算,别说那些初学 ...