转自:https://www.cnblogs.com/sunziying/p/6501045.html

  • 建立连接

  阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则connect返回.否则的话一直阻塞.
  非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回。返回的错误码为EINPROGRESS,表示正在进行某种过程.

  • 接收连接

  对于阻塞方式的倾听socket,accept在连接队列中没有建立好的连接时将阻塞,直到有可用的连接,才返回。
  非阻塞倾听socket,在有没有连接时都立即返回,没有连接时,返回的错误码为EWOULDBLOCK,表示本来应该阻塞。

  • 无阻塞的设置方法

   方法一:fcntl      //文件控制函数

int flag;
if (flag = fcntl(fd, F_GETFL, 0) <0) perror("get flag");
flag |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flag) < 0)perror("set flag");

   方法二:ioctl       //设备控制接口函数

int b_on = 1;
ioctl (fd, FIONBIO, &b_on); 

  • 读操作

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

因此,非阻塞的read调用一般这样写:

if ((nread = read(sock_fd, buffer, len)) < 0)
{if (errno == EWOULDBLOCK){return 0;              //表示没有读到数据}else return -1; //表示读取失败
}
else return nread;读到数据长度

  • 写操作

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

  对于写操作write,原理是类似的,非阻塞socket在发送缓冲区没有空间时会直接返回错误号EWOULDBLOCK,表示没有空间可写数据,如果错误号是别的值,则表明发送失败。如果发送缓冲区中有足够空间或者是不足以拷贝所有待发送数据的空间的话,则拷贝前面N个能够容纳的数据,返回实际拷贝的字节数。
非阻塞的write操作一般写法是:

int write_pos = 0;
int nLeft = nLen;while (nLeft > 0)
{int nWrite = 0;if ((nWrite = write(sock_fd, data + write_pos, nLeft)) <= 0){if (errno == EWOULDBLOCK){nWrite = 0;}else return -1; //表示写失败}nLeft -= nWrite;write_pos += nWrite;
}
return nLen;

ERROR IN PROGRESS

ERROR WOULD BLOCK

  •  Linux fcntl函数详解

功能描述:根据【文件描述词】来操作文件的特性。
头文件:
#include <unistd.h>
#include <fcntl.h>

函数原型:          
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);         
int fcntl(int fd, int cmd, struct flock *lock);

描述:
 fcntl()针对(文件)描述符提供控制.参数fd是被参数cmd操作(如下面的描述)的描述符. 针对cmd的值,fcntl能够接受第三个参数(arg)

fcntl函数有5种功能:
     1.复制一个现有的描述符(cmd=F_DUPFD).
         2.获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
            3.获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
            4.获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
            5.获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW).

cmd 选项:
F_DUPFD:返回一个如下描述的(文件)描述符:                           
    (1)最小的大于或等于arg的一个可用的描述符                         
    (2)与原始操作符一样的某对象的引用              
    (3)如果对象是文件(file)的话,返回一个新的描述符,这个描述符与arg共享相同的偏移量(offset)                    
    (4)相同的访问模式(读,写或读/写)                          
    (5)相同的文件状态标志(如:两个文件描述符共享相同的状态标志)                            
    (6)与新的文件描述符结合在一起的close-on-exec标志被设置成交叉式访问execve(2)的系统调用                     
F_GETFD:取得与文件描述符fd联合close-on-exec标志,类似FD_CLOEXEC.如果返回值和FD_CLOEXEC进行与运算结果是0的话,文件保持交叉式访问exec(),           否则如果通过exec运行的话,文件将被关闭(arg被忽略)                  
F_SETFD:设置close-on-exec旗标。该旗标以参数arg的FD_CLOEXEC位决定。                   
F_GETFL:取得fd的文件状态标志,如同下面的描述一样(arg被忽略)                    
F_SETFL:设置给arg描述符状态标志,可以更改的几个标志是:O_APPEND, O_NONBLOCK,O_SYNC和O_ASYNC。
F_GETOWN:取得当前正在接收SIGIO或者SIGURG信号的进程id或进程组id,进程组id返回成负值(arg被忽略)                    
F_SETOWN:设置将接收SIGIO和SIGURG信号的进程id或进程组id,进程组id通过提供负值的arg来说明,否则,arg将被认为是进程id

F_GETFL和F_SETFL的标志如下面的描述:            
O_NONBLOCK:非阻塞I/O;如果read(2)调用没有可读取的数据,或者如果write(2)操作将阻塞,read或write调用返回-1和EAGAIN错误                      O_APPEND     :强制每次写(write)操作都添加在文件大的末尾,相当于open(2)的O_APPEND标志         
O_DIRECT      :最小化或去掉reading和writing的缓存影响.系统将企图避免缓存你的读或写的数据.
                        如果不能够避免缓存,那么它将最小化已经被缓存了的数 据造成的影响.如果这个标志用的不够好,将大大的降低性能                      
O_ASYNC       :当I/O可用的时候,允许SIGIO信号发送到进程组,例如:当有数据可以读的时候

注意:      在修改文件描述符标志或文件状态标志时必须谨慎,先要取得现在的标志值,然后按照希望修改它,最后设置新标志值。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。

fcntl的返回值:  与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。
下列三个命令有特定返回值:F_DUPFD,F_GETFD,F_GETFL以及F_GETOWN。第一个返回新的文件描述符,第二个返回相应标志,最后一个返回一个正的进程ID或负的进程组ID。

转载于:https://www.cnblogs.com/yorkyang/p/9071868.html

socket编程-阻塞和非阻塞相关推荐

  1. 基于MFC的socket编程(异步非阻塞通信)

    对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其 ...

  2. Linux Socket网络编程UDP、TCP 阻塞与非阻塞 断线重连机制

    三种非阻塞模式的方法: (1) fcntl函数 int Mode = fcntl(sockfd, F_GETFL, 0);       //获取文件的Mode值     fcntl(sockfd, F ...

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

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

  4. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)...

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程并行与并发同步与异步阻塞与非阻塞CPU密集型与IO密集型 线程与进程 进程 前言 ...

  5. UDP socket 设置为的非阻塞模式

    UDP socket 设置为的非阻塞模式  Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct s ...

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

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

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

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

  8. linux网络编程--阻塞与非阻塞

    linux网络编程--阻塞与非阻塞 建立连接 接受连接 无阻塞的设置方式 read() write() 读操作 写操作 Linux fcntl函数详解 功能描述 函数原型 fcntl()函数五种功能 ...

  9. C++网络编程快速入门(三):阻塞与非阻塞式调用网络通信函数

    目录 阻塞与非阻塞定义 send与recv connect 一些问题 为什么要将监听socket设置为非阻塞 阻塞与非阻塞定义 阻塞模式指的是当前某个函数执行效果未达预期,该函数会阻塞当前的执行线程, ...

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

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

最新文章

  1. python3实现四元数到普通角度的转换程序
  2. R语言构建文本分类模型并使用LIME进行模型解释实战:文本数据预处理、构建词袋模型、构建xgboost文本分类模型、基于文本训练数据以及模型构建LIME解释器解释多个测试语料的预测结果并可视化
  3. YOLO 卷积层代码学习
  4. Java 使用 URLConnection 模拟 Http Get和Post 提交
  5. iptables如何添加容许某个端口的访问
  6. ubuntu c++ 实现自动回车键功能_从X86到ARM,实现C和C++语言90% Code自动迁移
  7. 金蝶国际公布2020年全年业绩,云业务收入增长45.6%
  8. qt整个窗口上绘制矩形与在窗口的子控件上绘制矩形
  9. Java final 关键字简述
  10. Matlab怎样将传递函数转换成差分方程
  11. zookeeper 日志查看_zookeeper 安装和集群配置
  12. SpringCloud之Eureka
  13. 【android】apk在线升级
  14. 自然语言处理(NLP)语义分析:“词汇级”语义分析【词义消歧、词义表示和学习】、“句子级”语义分析【浅层语义分析(语义角色标注)、深层语义分析】
  15. 古文觀止卷七_獲麟解_韓愈
  16. S3DIS 点云数据集的手动修复问题
  17. 网易云音乐数据服务之路
  18. mpvue开发微信小程序踩坑笔记
  19. Final Cut Pro 导出视频教程「上」
  20. 成都c语言编程培训机构,成都学c语言编程,成都学c语言编程去哪里,成都学c语言编程需要报培训班吗...

热门文章

  1. python 输出log_python:logging模块(记录打印日志)
  2. C语言中常见的内存相关的Bugs
  3. 【C++入门】C++ vector类
  4. kafka 消息顺序写入服务器
  5. 关于Apt注解实践与总结【包含20篇博客】
  6. execute与executeUpdate的区别
  7. Server Tomcat v8.0 Server at localhost failed to start.
  8. 苹果商店近期审核的问题
  9. CentOS 网络基础:(1)HostName和DNS
  10. careercup-位操作5.1