http://www.cnblogs.com/sunada2005/p/3591378.html

谓阻塞方式的意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可读,或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止。

而对于非阻塞状态,如果没有东西可读,或者不可写,读写函数马上返回,而不会等待。

非阻塞,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高

简单的讲,阻塞就是GET,非阻塞就是PUT

阻塞好控制,不发送完数据程序不会走下去。但是对性能有影响。
非阻塞不太好控制,可能和能力有关,但是性能会得到很大提升。

阻塞式的编程方便。
非阻塞的编程不方便,需要程序员处理各种返回值

阻塞处理简单,非阻塞处理复杂

阻塞效率低,非阻塞效率高

阻塞模式,常见的通信模型为多线程模型,服务端accept之后,对每个socket创建一个线程去recv。逻辑上简单,适用于并发量小(客户端数目少),连续传输大数据量的情况下,比如文件服务器。还有就是在客户端recv服务器消息的时候也经常用,因为客户端就一个socket,用阻塞模式不影响效率,而且编程逻辑上要简单得多。

非阻塞模式,常见的通信模型为select模型和IOCP模型。适用于高并发,数据量小的情况,比如聊天室。客户端多的情况下,如果采用阻塞模式,需要开很多线程,影响效率。另外,客户端一般不采用非阻塞模式。

一、socket阻塞和非阻塞有哪些不同
1. 建立连接
阻塞方式下,connect首先发送SYN请求到服务器,当客户端收到服务器返回的SYN的确认时,则connect返回,否则的话一直阻塞。

非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回,返回的错误码为EINPROGRESS,表示正在进行某种过程。

2. 接收连接
阻塞模式下调用accept()函数,而且没有新连接时,进程会进入睡眠状态,直到有可用的连接,才返回。

非阻塞模式下调用accept()函数立即返回,有连接返回客户端套接字描述符,没有新连接时,将返回EWOULDBLOCK错误码,表示本来应该阻塞。

3. 读操作
阻塞模式下调用read(),recv()等读套接字函数会一直阻塞住,直到有数据到来才返回。当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数。当sockt的接收缓冲区中的数据大于期望读取的字节数时,读取期望读取的字节数,返回实际读取的长度。

对于非阻塞socket而言,socket的接收缓冲区中有没有数据,read调用都会立刻返回。接收缓冲区中有数据时,与阻塞socket有数据的情况是一样的,如果接收缓冲区中没有数据,则返回错误号为EWOULDBLOCK,表示该操作本来应该阻塞的,但是由于本socket为非阻塞的socket,因此立刻返回。遇到这样的情况,可以在下次接着去尝试读取。如果返回值是其它负值,则表明读取错误。

因此,非阻塞的re

4.写操作
对于阻塞Socket而言,如果发送缓冲区没有空间或者空间不足的话,write操作会直接阻塞住,如果有足够空间,则拷贝所有数据到发送缓冲区,然后返回.

对于写操作write,原理和read是类似的,非阻塞socket在发送缓冲区没有空间时会直接返回错误号EWOULDBLOCK,表示没有空间可写数据,如果错误号是别的值,则表明发送失败。如果发送缓冲区中有足够空间或者是不足以拷贝所有待发送数据的空间的话,则拷贝前面N个能够容纳的数据,返回实际拷贝的字节数。
尤其注意非阻塞的socket,在建立连接时要兼容处理返回EINPROGRESS情况,在接收连接、读操作、写操作时要兼容处理返回EWOULDBLOCK错误码的情况,以上情况并非连接异常,而是网络延时或者套接字缓冲区满造成的,一般不宜做异常处理(如返回异常关闭套接字)。

简单点理解就是:

同步,就是我调用一个功能,该功能没有结束前,我死等结果。
异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)。
阻塞,就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。
非阻塞,就是调用我(函数),我(函数)立即返回,通过select通知调用者
同步IO和异步IO的区别就在于:数据拷贝的时候进程是否阻塞
阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回
--------------------- 
原文:https://blog.csdn.net/mayue_web/article/details/82873115

(一)socket阻塞与非阻塞问题

在创建socket函数中的第二个参数types用来指定服务类型,在Linux2.6.17版本起,除了之前的SOCK_STREAM(流式服务)、SOCK_UGRAM(数据报服务)以外,又增加了SOCK_NONBLOCK和SOCK_CLOEXEC,分别表示将创建的socket设置为非阻塞的和用fork创建的子进程在子进程中关闭该socket;

第一个问题:如何将socket设置为非阻塞的?

第一种,fcntl系统调用函数是用来控制文件描述符常用的属性和行为,通过此函数可以修改socket属性;

#include <fcntl.h>
int fcntl(int fd,int cmd,...)
fd是要被操作的文件描述符,cmd参数指定执行何种类型操作,常见的cmd有以下几种:

获取文件描述符标志  ----> F_GETFD   设置文件名描述符标志----->F_SETFD

获取文件描述符状态标志--->F_GETFL 设置文件名描述符状态标志----->F_SETFL

修改socket为非阻塞socket

int flags = fcntl(sockfd,F_GETFL,0);

fcntl(sockfd,F_SETFL,flags | SOCK_NONOBLOCK);

第二种:直接在创建socket时设置

int sockfd= socket(AF_INET,SOCK_STREAM | SOCK_NONOBLOCK,0);

注意accept返回的socket也是阻塞的,应用accept4函数将最后一个参数设置为SOCK_NONOBLOCK

int accept4(sockfd,(struct sockaddr*)&cli,&len,SOCK_NONBLOCK);

第二个问题:在完成三次握手之后,网络异常(掉线)或者客户端正常退出,对accept是否会有影响?

netstat -nt | grep hostport 查看此端口的TCP连接状态

掉线以及客户端退出都不会影响accept调用返回,由于accept只是从监听队列中取出连接,而不论连接状态处于何种状态,更不关心网络状态.不会因为监听队列中socket状态的变化而决定accept是否能调用成功。

第三个问题:关于socket选项的知识

#include <sys/socket.h>

int getsockopt(int sockfd,int level,int option_name,void *option_value,socklen_t *restrict option_len);

int setsockopt(int sockfd,int level,int option_name,const void *option_value,socklen_t  option_len);

level指定要操作那个协议的选项,通用socket选项的level是SOL_SOCKET,option_name 是指定选项的名字

常用的通用socket选项有:SO_REUSEADDR 重用本地址 、SO_RCVBUF --->TCP接受缓冲区大小、SO_SNDBUF --->TCP发送缓冲区大小、SO_LINGER 若有数据待发送则延缓关闭、TCP_MAXSEG  ---> TCP最大报文段大小 上述这几个必须在listen调用之前设置才有效。

socket选项一:SO_REUSEADDR

通过设置socket此选项可以强制使用处于time_wait状态的连接占用的socket地址,也可以通过修改内核参数/proc/sys/net/ipv4/tcp_tw_recycle来快速回收被关闭的连接socket,从而使得TCP连接根本不进入time_wait状态。进而允许本次程序重用socket地址

socket选项二:SO_RCVBUF SO_SNDBUF

SO_RCVBUF:TCP接受缓冲区的大小最小值为256字节 ,如果我们修改此大小小于256字节时,系统会忽略此次设置,最小值还是256字节

SO_SNDBUF:TCP发送缓冲区大小最小值是2048字节,是为了保证一个TCP连接有足够的空闲缓冲区处理拥塞,如果我们修改此大小,系统会将我们设置的值翻倍

也可以修改内核参数:/proc/sys/net/ipv4/tcp_rmem、/proc/sys/net/ipv4/tcp_wmem来强制TCP接受和发送缓冲区的大小没有最小值限制。

选项三:SO_LINGER

SO_LINGER用于控制close系统调用在关闭TCP连接时的行为,默认情况下,当我们使用close系统调用关闭socket时会立即返回,TCP模块将该socket对应的发送缓冲区的残留数据发送给对方

在设置此选项时,需要向函数传递Linger结构体:

struct linger

{

int l_onoff;//0未开启,1开启

int l_linger;//滞留时间

}

根据linger结构体中两个变量的值不同,close调用会有不同的方式

情况一:l_onoff==0;此时SO_LINGER不起作用,close使用默认行为关闭socket;

情况二:l_onoff != 0 && l_linger == 0;此时close调用立即返回,将该socket对应的发送缓冲区的数据发给对方,同时给对方发送一个复位报文段。这种情况给服务器提供了一个异常终止连接的方法;

情况三:l_onoff != 0 && l_linger >0;此时close的行为取决于两个条件:1.该socket对应的发送缓冲区是否还有残留数据;2.该socket是阻塞的还是非阻塞的;

对于阻塞的socket,close将等待一段长为l_linger的时间等TCP模块将发送缓冲区的数据发给对方并得到对方确认,返回-1并设置EWOULDBLOCK(不需要重新读写);

对于非阻塞的socket,close立即返回,此时需要根据返回值和error来判断残留数据是否发送完毕;如果tcp缓冲区还有数据需要发送,数据能够正确的发送到对端;在发送的最后一个包会加FIN标志;如果另一端也要关闭发FIN时,本端就会发RST,因为本端的SOCKET已经关了。
--------------------- 
作者:zhangyin_blog 
来源:CSDN 
原文:https://blog.csdn.net/weixin_41966991/article/details/81942349 
版权声明:本文为博主原创文章,转载请附上博文链接!

SOCK_NONBLOCK,accept4 阻塞与非阻塞SOCKET相关推荐

  1. socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)

    socket的阻塞模式和非阻塞模式 无论是Windows还是Linux,默认创建socket都是阻塞模式的 在Linux中,可以再创建socket是直接将它设置为非阻塞模式 int socket (i ...

  2. socket阻塞和非阻塞有哪些影响

    文章目录 一.阻塞非阻塞概念 二.socket阻塞和非阻塞有哪些影响 1.建立连接 connect 2.接收连接 accept 3.读操作 recv/read 4.写操作 write/send 5.简 ...

  3. socket阻塞和非阻塞模式

    socket阻塞和非阻塞模式 本文讨论Linux下的socket套接字 一.同步.异步阻塞和非阻塞 同步:主动请求并等待IO操作完成的方式 异步:主动请求数据后,可以去处理其它任务,随后等待IO操作完 ...

  4. Socket阻塞,非阻塞,同步,异步

    1.socket 阻塞,非阻塞(select) http://blog.csdn.net/piaojun_pj/article/details/5991968/ http://blog.chinaun ...

  5. linux socket 阻塞与非阻塞,同步与异步

    在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端:  同步:       所谓同步,就是在c端发出 ...

  6. Socket阻塞与非阻塞,同步与异步、I/O模型

    [原文链接] 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步:       所谓同步,就是在发出一 ...

  7. socket阻塞和非阻塞的区别

    socket阻塞和非阻塞的区别 简单点说: 阻塞就是干不完不准回来,    非组赛就是你先干,我现看看有其他事没有,完了告诉我一声 我们拿最常用的send和recv两个函数来说吧... 比如你调用se ...

  8. 从 Linux 源码看 Socket 的阻塞和非阻塞

    转载自 从 Linux 源码看 Socket 的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 大部分高性能网络框架采用的是非阻塞模式.笔者这 ...

  9. socket阻塞与非阻塞,同步与异步

    转自:http://blog.csdn.net/hguisu/article/details/7453390 socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理解 在进行网 ...

  10. 【精辟】socket阻塞与非阻塞,同步与异步,select,pool,epool

    socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调 ...

最新文章

  1. 2018年《环球科学》十大科学新闻出炉:霍金逝世、贺建奎事件位列前二
  2. 知识图谱论文阅读(十八)【KDD2019】AKUPM: Attention-Enhanced Knowledge-Aware User Preference Model for Recommend
  3. Android中XML数据解析
  4. 神操作!员工索要工资遭遇“假转账”:转了生气又撤销
  5. 关于结合测试时,数据准备的一些注意点 (之开始篇:如何能更快,更好的准备测试数据)。
  6. java 视频转码工具类_JavaCV入门指南:FrameConverter转换工具类及CanvasFrame图像预览工具类(javaCV教程完结篇)...
  7. libevhtp介绍与demo构建
  8. java comparable与_Java中Comparable和Comparator区别
  9. Python[装饰器]
  10. 第03章-二进制、八进制、十进制、十六进制之间的转换-深博-专题视频课程
  11. 设计模式学习——代理模式(proxy)
  12. 投影仪幕布增益_别再说幕布是花瓶 投影幕布的作用原来这么大
  13. 计算机绘图综合训练大题,工程制图与计算机绘图综合实训报告汇编.doc
  14. bam文件读取_科学网—Pacbio Sequel两种bam文件解析 - 卢锐的博文
  15. Linux命令老是记不住?一篇文章帮你解决。Linux常用命令汇总
  16. STM32机器人控制开发教程No.3 使用遥控控制电机/舵机(基于HAL库)
  17. go每日新闻--2020-12-23
  18. 移动代理服务器 Mobile Agent Server(MAS)
  19. 以太坊 权益证明(五)
  20. 网络推广-方法和技巧

热门文章

  1. 我的世界怎么在网易的服务器里显示皮肤,我的世界怎么显示皮肤,怎么在嗨皮咳嗽上显示自定义皮肤...
  2. 【超详细】output level 和 pull up/ pull down 的真正区别
  3. 高德地图API学习笔记
  4. Driverjs-前端引导页组件
  5. 二进制炸弹——拆弹实验
  6. 生活随笔--拆弹专家
  7. 关于荣耀che1-cl20手机制作服务器失败的事
  8. 云上PDF怎么删除页眉页脚_有办法了!批量删除多个Word页眉页脚
  9. 单片机中存储器扩展位地址线怎么算_单片机程序存储器的扩展
  10. python除数为0报错_python——异常