精华内容
下载资源
问答
  • Linux下socket阻塞模式与非阻塞模式

    千次阅读 2012-02-22 18:15:10
    1、阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是0接收到数据大小,特别:返回值时并且(errno == EINTR || errno == EWOULDBLOCK || errno...
     1、阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是<0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值<0时并且(errno
     == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,继续接收。只是阻塞模式下recv会阻塞着接收数据,非阻塞模式下如果没有数据会返回,不会阻塞着读,因此需要循环读取)。

    2、阻塞模式与非阻塞模式下write的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞write返回值没有区分,都是<0:出错,=0:连接关闭,>0发送数据大小,特别:返回值<0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,继续发送。只是阻塞模式下write会阻塞着发送数据,非阻塞模式下如果暂时无法发送数据会返回,不会阻塞着write,因此需要循环发送)。

    3、阻塞模式下read返回值 < 0 && errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN时,连接异常,需要关闭,read返回值 < 0 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)时表示没有数据,需要继续接收,如果返回值大于0表示接送到数据。
      非阻塞模式下read返回值 < 0表示没有数据,= 0表示连接断开,> 0表示接收到数据。
      这2种模式下的返回值是不是这么理解,有没有跟详细的理解或跟准确的说明?

    4、阻塞模式与非阻塞模式下是否send返回值< 0 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)表示暂时发送失败,需要重试,如果send返回值<= 0, && errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN时,连接异常,需要关闭,如果send返回值 > 0则表示发送了数据?send的返回值是否这么理解,阻塞模式与非阻塞模式下send返回值=0是否都是发送失败,还是那个模式下表示暂时不可发送,需要重发?

    5、很多人说阻塞模式下read会阻塞着读,是否这样?我和同事试了不会阻塞read。

    6、网络上找了很多资料,说的都很笼统,就分大于0,小于0,等于0,并没有区分阻塞与非阻塞,更没有区分一个错误号,希望哪位高手能按上面的问题逐条回答一下,越详细越好,平时少上CSDN,分少,见谅。
    展开全文
  • LINUX 下非阻塞模式下TCP 研究

    千次阅读 2013-04-24 16:57:16
    本文是其他论坛中对此TCP描述的研究。...在阻塞模式下,send函数的过程是将应用程序请求发送的数据拷贝到发送缓存中发送并得到确认后再返回.但由于发送缓存的存在,表现为:如果发送缓存大小比请求发送

    本文是其他论坛中对此TCP描述的研究。我只是将这些帖子进行了汇总,觉得很不错!希望对大家受用!

    tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据.


    阻塞模式下,send函数的过程是将应用程序请求发送的数据拷贝到发送缓存中发送并得到确认后再返回.但由于发送缓存的存在,表现为:如果发送缓存大小比请求发送的大小要大,那么send函数立即返回,同时向网络中发送数据;否则,send向网络发送缓存中不能容纳的那部分数据,并等待对端确认后再返回(接收端只要将数据收到接收缓存中,就会确认,并不一定要等待应用程序调用recv);
    非阻塞模式下,send函数的过程仅仅是将数据拷贝到协议栈的缓存区而已,如果缓存区可用空间不够,则尽能力的拷贝,返回成功拷贝的大小;如缓存区可用空间为0,则返回-1,同时设置errno为EAGAIN.



    linux下可用sysctl -a | grep net.ipv4.tcp_wmem查看系统默认的发送缓存大小:
    net.ipv4.tcp_wmem = 4096 16384 81920
    这有三个值,第一个值是socket的发送缓存区分配的最少字节数,第二个值是默认值(该值会被net.core.wmem_default覆盖),缓存区在系统负载不重的情况下可以增长到这个值,第三个值是发送缓存区空间的最大字节数(该值会被net.core.wmem_max覆盖).
    根据实际测试,如果手工更改了net.ipv4.tcp_wmem的值,则会按更改的值来运行,否则在默认情况下,协议栈通常是按net.core.wmem_default和net.core.wmem_max的值来分配内存的.

    应用程序应该根据应用的特性在程序中更改发送缓存大小:

    需要注意的是,虽然将发送缓存设置成了10k,但实际上,协议栈会将其扩大1倍,设为20k.


    -------------------实例分析----------------------


    在实际应用中,如果发送端是非阻塞发送,由于网络的阻塞或者接收端处理过慢,通常出现的情况是,发送应用程序看起来发送了10k的数据,但是只发送了2k到对端缓存中,还有8k在本机缓存中(未发送或者未得到接收端的确认).那么此时,接收应用程序能够收到的数据为2k.假如接收应用程序调用recv函数获取了1k的数据在处理,在这个瞬间,发生了以下情况之一:

    A. 发送应用程序认为send完了10k数据,关闭了socket:
    发送主机作为tcp的主动关闭者,连接将处于FIN_WAIT1的半关闭状态(等待对方的ack),并且,发送缓存中的8k数据并不清除,依然会发送给对端.如果接收应用程序依然在recv,那么它会收到余下的8k数据(这个前题是,接收端会在发送端FIN_WAIT1状态超时前收到余下的8k数据.),然后得到一个对端socket被关闭的消息(recv返回0).这时,应该进行关闭.

    B. 发送应用程序再次调用send发送8k的数据:
    假如发送缓存的空间为20k,那么发送缓存可用空间为20-8=12k,大于请求发送的8k,所以send函数将数据做拷贝后,并立即返回8192;

    假如发送缓存的空间为12k,那么此时发送缓存可用空间还有12-8=4k,send()会返回4096,应用程序发现返回的值小于请求发送的大小值后,可以认为缓存区已满,这时必须阻塞(或通过select等待下一次socket可写的信号),如果应用程序不理会,立即再次调用send,那么会得到-1的值,在linux下表现为errno=EAGAIN.


    C. 接收应用程序在处理完1k数据后,关闭了socket:
    接收主机作为主动关闭者,连接将处于FIN_WAIT1的半关闭状态(等待对方的ack).然后,发送应用程序会收到socket可读的信号(通常是select调用返回socket可读),但在读取时会发现recv函数返回0,这时应该调用close函数来关闭socket(发送给对方ack);

    如果发送应用程序没有处理这个可读的信号,而是继续调用send,那么第一次会像往常一样继续填充缓存区,然后返回,但如果再次调用send,进程会收到SIGPIPE信号,该信号的默认响应动作是退出进程.


    D. 交换机或路由器的网络断开:
    接收应用程序在处理完已收到的1k数据后,会继续从缓存区读取余下的1k数据,然后就表现为无数据可读的现象,这种情况需要应用程序来处理超时.一般做法是设定一个select等待的最大时间,如果超出这个时间依然没有数据可读,则认为socket已不可用.

    发送应用程序会不断的将余下的数据发送到网络上,但始终得不到确认,所以缓存区的可用空间持续为0,这种情况也需要应用程序来处理.

    如果不由应用程序来处理这种情况超时的情况,也可以通过tcp协议本身来处理,具体可以查看sysctl项中的:
    net.ipv4.tcp_keepalive_intvl
    net.ipv4.tcp_keepalive_probes
    net.ipv4.tcp_keepalive_time

    所以,要想编写优秀的socket程序也是很不容易的.特别是在为应用做优化时,很多工作都非常的烦琐.

    ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××


    展开全文
  • 这篇文章主要介绍了Linux UDP socket 设置为的非阻塞模式阻塞模式区别的相关资料,需要的朋友可以参考 Linux UDP socket 设置为的非阻塞模式阻塞模式区别 UDP socket 设置为的非阻塞模式  ? 1 ...

    这篇文章主要介绍了Linux UDP socket 设置为的非阻塞模式与阻塞模式区别的相关资料,需要的朋友可以参考下

    Linux UDP socket 设置为的非阻塞模式与阻塞模式区别

    UDP socket 设置为的非阻塞模式 

    ?

    1

    Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct sockaddr *)&SockAddr,&ScokAddrLen);

    UDP socket 设置为的阻塞模式 

    ?

    1

    Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), 0, (struct sockaddr *)&SockAddr,&ScokAddrLen);

    Linux socket编程之阻塞套接字和非阻塞套接字

      每一个TCP套接口有一个发送缓冲区,可以用SO_SNDBUF套接口选项来改变这个缓冲区的大小。当应用进程调用 write时,内核从应用进程的缓冲区中拷贝所有数据到套接口的发送缓冲区。如果套接口的发送缓冲区容不下应用程序的所有数据(或是应用进程的缓冲区大于套接口发送缓冲区,或是套接口发送缓冲区还有其他数据),应用进程将被挂起(睡眠)。这里假设套接口是阻塞的,这是通常的缺省设置。内核将不从write系统调用返回,直到应用进程缓冲区中的所有数据都拷贝到套接口发送缓冲区。因此从写一个TCP套接口的write调用成功返回仅仅表示我们可以重新使用应用进程的缓冲区。它并不告诉我们对端的 TCP或应用进程已经接收了数据。 

        TCP取套接口发送缓冲区的数据并把它发送给对端TCP,其过程基于TCP数据传输的所有规则。对端TCP必须确认收到的数据,只有收到对端的ACK,本端TCP才能删除套接口发送缓冲区中已经确认的数据。TCP必须保留数据拷贝直到对端确认为止。

    1 输入操作: read、readv、recv、recvfrom、recvmsg

        如果某个进程对一个阻塞的TCP套接口调用这些输入函数之一,而且该套接口的接收缓冲区中没有数据可读,该进程将被投入睡眠,直到到达一些数据。既然 TCP是字节流协议,该进程的唤醒就是只要到达一些数据:这些数据既可能是单个字节,也可以是一个完整的TCP分节中的数据。如果想等到某个固定数目的数据可读为止,可以调用readn函数,或者指定MSG_WAITALL标志。

        既然UDP是数据报协议,如果一个阻塞的UDP套接口的接收缓冲区为空,对它调用输入函数的进程将被投入睡眠,直到到达一个UDP数据报。

        对于非阻塞的套接口,如果输入操作不能被满足(对于TCP套接口即至少有一个字节的数据可读,对于UDP套接口即有一个完整的数据报可读),相应调用将立即返回一个EWOULDBLOCK错误。

    2 输出操作:write、writev、send、sendto、sendmsg

        对于一个TCP套接口,内核将从应用进程的缓冲区到该套接口的发送缓冲区拷贝数据。对于阻塞的套接口,如果其发送缓冲区中没有空间,进程将被投入睡眠,直到有空间为止。

        对于一个非阻塞的TCP套接口,如果其发送缓冲区中根本没有空间,输出函数调用将立即返回一个EWOULDBLOCK错误。如果其发送缓冲区中有一些空间,返回值将是内核能够拷贝到该缓冲区中的字节数。这个字节数也称为不足计数(short count)

        UDP套接口不才能在真正的发送缓冲区。内核只是拷贝应用进程数据并把它沿协议栈向下传送,渐次冠以UDP头部和IP头部。因此对一个阻塞的UDP套接口,输出函数调用将不会因为与TCP套接口一样的原因而阻塞,不过有可能会因其他的原因而阻塞。

    感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

    展开全文
  • 阻塞即同步,一件事情没有完成必然不会往执行; 非阻塞即异步,不管当前事情有没有完成,都会往执行; linux socket下面,最常用的函数便是recvfrom/sendto, recv/send,前面那一对是基于UDP的,后面是基于TCP...

    阻塞即同步,一件事情没有完成必然不会往下执行;

    非阻塞即异步,不管当前事情有没有完成,都会往下执行;

    linux socket下面,最常用的函数便是recvfrom/sendto, recv/send,前面那一对是基于UDP的,后面是基于TCP。这两组函数都有阻塞和非阻塞方式,可以通过fcntl函数设置。

    说到这里,顺便提一下fcntl函数,这个系统调用是用来重新设置打开设备/文件的属性,包括读、写、非阻塞等,而无需重新打开文件。


    值得一提的是,采用非阻塞形式的I/O可以用来编写简单的心跳检测程序,测试服务器是否在运行。代码之后补充。。。。。。

    基本流程如下:

    if (-1 == fcntl(fd, F_SETFL, O_NONBLOCK))// set the fd to nonblock
    {       printf("fcntl socket error!\n");
           return -1;
    }
    
    fd_set readfds;
    FD_ZERO(&readfds);//clean
    FD_SET(fd, &readfds);//add
    
    struct timeval tv={mysec,0};//set the time 
    
    if (selectfd+1,&readfds,NULL, NULL, &tv) > 0){
    	recvfrom/recv();
    	printf("recv data from server in %d secs\n", mysec);//server is working...
    	
    }
    else{
    	printf("don't recv data from server in %d secs\n", mesec);//server isn't working...
    }




    展开全文
  • 阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方 式来判断具体操作是否成功。(对于connect,accpet操作,通过select判断, 对于recv,recvfrom,send,sendto通过返回值+错误码来判断) IO模式设置: 一般...
  • socket缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出...这就是TCP套接字的阻塞模式。所谓阻塞,就是上一步动作没有完成,一步动作将暂停,直到上一步动作完成后才能继续,以保持同步性。
  • 本质区别现实例子同步模式由处理消息者自己去等待消息是否被触发我去银行办理业务,选择排队等,排到头了就办理。异步模式由触发机制来通知处理消息者我去银行办理业务,取一个小纸条上面有我的号码,等到排到我这一号...
  • //设置非规范模式下的超时时长和最小字符数:阻塞模式起作用 opt.c_cc[VTIME] = vtime; //VTIME与VMIN配合使用,是指限定的传输或等待的最长时间 单位:0.1S tcflush (fd, TCIFLUSH); /* TCIFLUSH-- update the...
  • [Linux]非阻塞模式下socket发送数据

    千次阅读 2014-10-29 23:13:58
    #include #include #include #include #include #include #include #include #include #include #include ...#define BUF_SIZE 1024*128 ...int main(const int argc,char* const argv[]) ... struct soc
  • linux socket 阻塞模式下recv()返回11(EAGAIN )的可能原因:   1,设置了接收超时为非0。 参考至:http://stackoverflow.com/questions/735249/blocking-socket-returns-eagain   2,网络质量差,例如:...
  • 非阻塞IO:非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。(对于connect,accpet操作,通过select判断,对于recv,recvfrom,send,sendto通过返回值+错误码来判断) IO模式...
  • window和linux下,设置socket为阻塞模式

    千次阅读 2014-07-04 09:22:55
    一下一段小程序,给定的是跨平台window和linux,设置socket为阻塞模式 void SetSocketUnBlock(SOCKET hSocket) { #ifdef WIN32  u_long mode = 1;  if (SOCKET_ERROR == ioctlsocket(hSocket, (long)...
  • 设置linux的socket的非阻塞模式

    千次阅读 2013-04-22 09:53:11
    int setnonblocking(int sockfd)  { if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) { return -1; } return 0; } ...TCP_CORK选项与TCP_NODELAY一样,是控制Nag
  • Linux阻塞connect

    2016-01-04 22:11:10
    阻塞模式下,在I/O操作完成前,执行操作的函数一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回-1,而不管I/O是否完成,该函数所在的线程会继续运行。客户端...
  • Socket 阻塞模式和非阻塞模式

    千次阅读 2013-04-24 14:46:12
    阻塞模式下,在I/O操作完成前,执行的操作函数一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在的线程会继续运行。 在阻塞...
  • Linux串口编程的阻塞与否可以在open函数中设置,例如: 打开时使用: fd = open(USAR1, O_RDWR | O_NOCTTY );//阻塞式读写 fd = open("/dev/ttyAT2",O_RDWR|O_NOCTTY|O_NDELAY); //非阻塞读写 除了用open函数...
  • - 进程的阻塞 - 文件描述符 - 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通...
  • Socket的阻塞模式和非阻塞模式

    千次阅读 2018-07-04 16:07:34
    阻塞模式下,在I/O操作完成前,执行的操作函数一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在的线程会继续运行。在阻塞模式...
  • 阻塞模式与非阻塞模式

    千次阅读 2009-10-08 15:18:00
    这两天在看一个FTP客户端的代码,里面用到了socket的非阻塞模式。之前没有接触个这方面。看了APUE,里面只是简单说了,这个是文件状态标志。。在linux下什么都是以文件形式存在的,设备也是。访问设备可以通过...
  • linux 串口阻塞与非阻塞参数设置

    万次阅读 2015-10-17 15:47:21
    在串口设置中,有以下两个参数可以决定是否阻塞。 在打开串口时不加O_NODELAY,可用下面的第二种方法,来进行阻塞/非阻塞的... 非规范模式读取时的最小字符数,设为0则为非阻塞,如果设为其它值则阻塞,直到读到到对
  • 文章目录进程等待的非阻塞模式阻塞模式进程程序替换作用原理应用场景守护进程bash(命令行解释器)接口exec函数簇minishell 进程等待的非阻塞模式阻塞模式 1.WNONHANG 2.搭配循环使用 循环判断条件:waitpid...
  • linux阻塞阻塞文件读写

    千次阅读 2018-08-09 10:38:07
    在非阻塞方式,若设备不可读写,进程放弃读写,继续向执行;若设备文件可读写,则对设备文件进行读写。2.使用及实现原理  使用:  要使用非阻塞方式读写设备文件,则在调用open()函数时,添加O_NO...
  • Linux下socket阻塞、非阻塞详解

    千次阅读 2014-12-12 11:56:02
    阻塞就是干不完不准回来,  非组赛就是你先干,我现看看有其他事没有,完了告诉我一声 我们拿最常用的send和recv两个函数来说吧...  比如你调用send函数发送一定的Byte,在系统内部send做的工作其实只是把数据...
  • 主要贴代码,参考的也是别人的代码,但是发现有BUG,努力修正后实现多台客户段与一台服务器通信:在非阻塞模式下,服务器和客户端可以自由发消息,不必等待回答,目前服务器发的消息,所有客户端都会收到此消息。...
  • linux 串口阻塞和非阻塞

    千次阅读 2012-09-03 23:49:09
    有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。 不过在一般的程序中我们使用O_NOBLOCK参数,O_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,957
精华内容 43,982
关键字:

linux下阻塞模式

linux 订阅