IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Linux socket里的send和recv,阻塞与非阻塞socket、TCP与UDP的区别 -> 正文阅读

[网络协议]Linux socket里的send和recv,阻塞与非阻塞socket、TCP与UDP的区别

1. send函数

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数:sockfd是socket()的返回值,文件描述符;buf是待发送数据所在的数据区的指针;len是发送数据的长度;flags标志位,默认为0。

返回值:(阻塞与非阻塞没有区别)>0表示成功将数据复制到缓冲区中,返回的值表示发送的字节数;=0表示对方主动关闭了连接过程;<0表示出错,会返回SOCKET_ERROR。

send发送数据实际上是将数据(应用层buf中的数据)拷贝到套接字sockfd的缓冲区(内核中的sockfd对应的发送缓冲区)中,内核中的发送缓存中的数据由协议(TCP,UDP没有发送缓冲区)传输。send函数将buf中的数据成功拷贝到发送缓冲区后就返回了,如果协议后续发送数据到接收端出现网络错误的话,那么下一个socket函数就会返回SOCKET_ERROR。

send发送数据时,首先比较待发送的数据长度len和套接字sockfd的发送缓冲区的长度,

  (1)如果待发送数据的长度len大于sockfd发送缓冲区的长度,则返回SOCKET_ERROR;

  (2)如果待发送数据的长度len小于等于sockfd发送缓冲区的长度,则再检查协议是否正在发送sockfd的发送缓冲区的数据, 

      【1】如果正在发送,则等协议把发送缓冲区中的数据发送完毕后(这里应该有阻塞和非阻塞的区别,阻塞的话等待数据的发送完毕,非阻塞的话立即返回,并将errno置为EAGAIN),将待发送的数据拷贝到sockfd的发送缓冲区中;

      【2】如果没有在发送数据,或发送缓冲区中没有数据,则比较sockfd的发送缓冲区的剩余空间和待发送数据的长度len:

        A. 如果剩余空间大于待发送数据的长度len,则将buf里的数据拷贝到剩余空间里;

        B. 如果剩余空间小于待发送数据的长度len,则等待协议把sockfd的发送缓冲区中的数据发送腾出空间(收到接收方的确认)(阻塞与非阻塞的区别,见ps的1),再将待发送数据拷贝到发送缓冲区中。

PS:1. 如果剩余空间小于待发送数据的长度len,阻塞socket会等待协议将发送缓冲区中的数据发送(缓冲区应该要收到接收方的确认之后,才能腾出空间),再拷贝待发送的数据并返回;非阻塞socket会尽力拷贝(能拷多少拷多少),返回已拷贝字节的大小,如果缓冲区可用空间为0,则返回-1,并置errno为EAGAIN((不确定)。

2. TCP有发送缓冲区,数据发送是协议发送发送缓冲区的内容;UDP没有发送缓冲区,UDP有数据要发送时,直接发送到网络上,不会缓存。

3. 接收端的sockfd缓冲区(内核的缓冲区)收到数据包后,就会返回ACK,不会等待recv到用户空间再返回。

2. recv函数

#include <sys/types.h>

?#include <sys/socket.h>

?ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数:sockfd是socket()的返回值,文件描述符;buf是接受数据的缓存区的指针;len是发送数据的长度;flags标志位,默认为0。

返回值:(阻塞与非阻塞没有区别)>0表示成功,此时的值是接收到的数据大小;=0表示对方调用了close API来关闭连接;<0表示出错,<0且(errno?==?EINTR?||?errno?==?EWOULDBLOCK?||?errno?==?EAGAIN)的情况下认为连接是正常的,继续接收,此时,errno被设为下面的某个值:

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

  EBADF:sock不是有效的描述词

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

  EFAULT:内存空间访问出错

  EINTR:操作被信号中断,连接正常,继续接收

  EINVAL:参数无效

  ENOMEM:内存不足

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

  ENOTSOCK:sock索引的不是套接字

recv仅仅将接收到的数据(存储在内核的接受缓冲区)拷贝到buf(应用层用户的缓存区)中,真正的接受数据是由协议(TCP/UDP,UDP调用的函数名称不同)完成的。

recv先检查sockfd的发送缓冲区中有没有数据:

  (1)如果发送缓冲区中有数据,先等待sockfd的发送缓冲区的数据被协议发送完毕;如果协议在传送发送缓冲区的数据时出现网络错误,则返回SOCKET_ERROR;

  (2)如果sockfd发送缓冲区中的数据发送完毕或者发送缓冲区中没有数据,则检查sockfd的接收缓冲区,如果接受缓冲区中没有数据或者协议正在接收数据,那么recv一直等待(阻塞socket将等待,非阻塞socket直接返回-1,errno置为EWOULDBLOCK),直到协议将数据接受完毕;当协议把数据接收完毕,recv函数就把sockfd的接受缓冲区中的数据拷贝到buf中,然后返回拷贝的字节数。(注:协议接收到的数据的长度可能大于buf的长度,此时要调用几次recv函数才能把sockfd接受缓冲区中的数据拷贝完。)

?3. 阻塞与非阻塞的区别

发送时:在发送缓冲区的空间大于待发送数据的长度的条件下,阻塞socket一直等到有足够的空间放待发送的数据,将数据拷贝到发送缓冲区中才返回;非阻塞socket在没有足够空间时,会拷贝部分,并返回已拷贝的字节数,置errno为EWOULDBLOCK(不确定置为啥)。

接收时:如果sockfd发送缓冲区中有数据,或接受缓冲区中无数据,或协议正在接受数据,阻塞socket都将等待,直到有数据可以拷贝到用户程序中;非阻塞socket会返回-1,置errno为EWOULDBLOCK,表示“没有数据,回头来看”。

4. TCP与UDP的区别,TCO如何使用缓冲区实现流量控制

TCP有发送缓冲区和接收缓冲区;UDP只有接受缓冲区,UDP发送时不缓存,直接发送出去。对于接收缓冲区,TCP和UDP的recv操作相同,分为阻塞与非阻塞socket。

TCP的sockfd的接收缓冲区如果满了之后,接收端通知发送端,接收窗口关闭(win=0),保证了TCP套接口接收缓冲区不溢出,从而实现可靠传输;如果发送方无视窗口大小,仍然发送,则接收方TCP丢失收到的包。这就是TCP的流量控制(流量控制是点对点的)

UDP的接受缓冲区满了之后,对方并不知道,新来的数据报无法进入缓冲区,直接被丢弃,所以UDP没有流量控制,快的发送者可以将慢的接收方淹没,导致接收方丢弃数据包。

5. send和recv图示

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:45:03  更:2021-08-17 15:46:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 17:16:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码