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是否都是发送失败,还是那个模式下表示暂时不可发送,需要 重发?

1. send函数

int send( SOCKET s, const char FAR *buf, int len, int flags );

不论是客户端还是服务器端应用程序都用send函数来向TCP连接的另一端发送数据。

客户端程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。

该函数的:

第一个参数指定发送端套接字描述符;

第二个参数指明一个存放应用程序要发送数据的缓冲区;

第三个参数指明实际要发送的数据的字节数;

第四个参数一般置0。

这里只描述同步Socket的send函数的执行流程。当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议 是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么 send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小send就一直等待协议把s的发送缓冲中的数据发送完,如果len小于剩余 空间大小send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。

要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除send外的Socket函数在执 行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返回 SOCKET_ERROR)

注意:在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。

Send函数的返回值有三类:

(1)返回值=0:

(2)返回值<0:发送失败,错误原因存于全局变量errno中

(3)返回值>0:表示发送的字节数(实际上是拷贝到发送缓冲中的字节数)

错误代码:

EBADF 参数s 非合法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此操作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。

2.  recv函数

int recv( SOCKET s,     char FAR *buf,      int len,     int flags     );

不论是客户端还是服务器端应用程序都用recv函数从TCP连接的另一端接收数据。

该函数的:

第一个参数指定接收端套接字描述符;

第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

第三个参数指明buf的长度;

第四个参数一般置0。

这里只描述同步Socket的recv函数的执行流程。当应用程序调用recv函数时,recv先等待s的发送缓冲 中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,如果s的发送缓冲中没有数 据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,只到 协议把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以 在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。

注意:在Unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。

默认情况下socket是阻塞的。

阻塞与非阻塞recv返回值没有区别,都是:

<0 出错

=0 对方调用了close API来关闭连接

>0 接收到的数据大小,

特别地:返回值<0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,继续接收。

只是阻塞模式下recv会一直阻塞直到接收到数据,非阻塞模式下如果没有数据就会返回,不会阻塞着读,因此需要循环读取)。

返回说明:

(1)成功执行时,返回接收到的字节数。

(2)若另一端已关闭连接则返回0,这种关闭是对方主动且正常的关闭

(3)失败返回-1,errno被设为以下的某个值

EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时

EBADF:sock不是有效的描述词

ECONNREFUSE:远程主机阻绝网络连接

EFAULT:内存空间访问出错

EINTR:操作被信号中断

EINVAL:参数无效

ENOMEM:内存不足

ENOTCONN:与面向连接关联的套接字尚未被连接上

ENOTSOCK:sock索引的不是套接字

关于socket阻塞与非阻塞情况下的recv、send、read、write返回值---部分内容可能不确切,待讨论的更多相关文章

  1. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值(转载)

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  2. UNIX网络编程——关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有 区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回 ...

  3. socket阻塞与非阻塞,同步与异步、I/O模型,select与poll、epoll比较

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

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

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

  5. 【2018.08.13 C与C++基础】网络通信:阻塞与非阻塞socket的基本概念及简单实现

    一.前言 最近在做Matalb/Simulink与C/C++的混合编程,主要是完成TCP.UDP.SerialPort等常见通信方式的中间件设计,为Simulink模型提供数据采集及解析模块. 问题在 ...

  6. linux下recv 、send阻塞、非阻塞区别和用法

    非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:       基本概念: 阻塞IO:: socket 的阻塞模式 ...

  7. socket recv阻塞与非阻塞error总结

    recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结. 首先阻塞接收的re ...

  8. socket阻塞与非阻塞,同步与异步、I/O模型

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

  9. Socket调用方式(同步,异步,阻塞,非阻塞)

    同步: 我调用一个功能,该功能没有结束前,我死等结果. 异步: 当一个异步过程调用发出后,调用者不能立刻得到结果.该功能在完成后,通过状态.通知和回调来通知调用者. 同步和非同步关注的是调用者是否等待 ...

随机推荐

  1. Bootstrap~表单Form

    回到目录 在进行自己的后台改版时,大体布局都使用了bootstrap,剩下的表单部分没理由不去使用它,对于表单的美化和布局,bootstrap做的也是很不错的,有大气的边框,多功能的按钮及宏观的表单布 ...

  2. 最大ASCII的和问题

    问题:One day when you are going to clear all your browsing history, you come up with an idea: You want ...

  3. [DevExpress]DxValidationProvider分享

    前些日子从研究所临时调回公司,帮忙做另外一个项目的控件验证工作,其实内容非常的简单,就是将用户即将提交至服务器的数据先做一个本地验证,以达到减少服务器压力.提高用户体验的目的. 附上一张图片 这是官方 ...

  4. MFC中菜单栏使用

    1.新建项目: 选择MFC应用程序,应用程序类型选择“基于对话框”: 本文中项目名为:MenuTest 2.新建菜单栏资源: 找到资源视图,右键MenuTest.re选择“添加资源”——选择Menu, ...

  5. Oracle dump 分析secondary key

    验证secondary key 含有主键列数据 SQL> select object_name,object_id,OBJECT_TYPE from user_objects; OBJECT_N ...

  6. 网络编程I/O功能介绍

    read和write #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(in ...

  7. 3.IP协议,ARP协议,RARP协议

    1.IP协议 IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输.要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制 ...

  8. Webpack单元测试,e2e测试

    此篇文章是续 webpack多入口文件.热更新等体验,主要说明单元测试与e2e测试的基本配置以及相关应用. 一.单元测试 实现单元测试框架的搭建.es6语法的应用.以及测试覆盖率的引入. 1. 需要安 ...

  9. canvas——路径搜索

    在前一篇博客中随机生成迷宫,现在就以随机生成的迷宫为地图,开始寻找路径. 迷宫寻路也可以使用DFS,BFS,但常见的是A*算法,它是启发式搜索算法的一种,效率相比前两者也更高.接下来以A*算法为例,迷 ...

  10. 在iOS App 中添加启动画面

    你可以认为你需要为启动画面编写代码,然而Apple 让你可以非常简单地在Xcode中完成.不需要编写代码,你仅需要在Xcode中进行一些配置. 1.什么是启动画面(Splash Screen)? 启动 ...