UNIX网络编程——send与recv函数详解
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);
- send和recv的前3个参数等同于read和write;
- flags参数值为0或为下图列出的一个或多个常值的逻辑或。
| flags | 说明 | recv | send |
| MSG_DONTROUTE | 绕过路由表查找 | • | |
| MSG_DONTWAIT | 仅本操作非阻塞 | • | • |
| MSG_OOB | 发送或接收带外数据 | • | • |
| MSG_PEEK | 窥看外来消息 | • | |
| MSG_WAITALL | 等待所有数据 | • |
- MSG_DONTROUTE:是send函数使用的标志。本标志告诉内核目的主机在某个直接连接的本地网络上,因而无须执行路由表查找。这个既可以使用MSG_DONTROUTE标志针对单个输出操作开启,也可以使用SO_DONTROUTE套接字选项针对某个给定套接字上的所有输出操作开启。
- MSG_DONTWAIT:本标志在无需打开相应套接字的非阻塞标志的前提下,把单个I/O操作临时指定为非阻塞,接着执行I/O操作,然后关闭非阻塞标志。
- MSG_OOB:表示能够接收和发送带外的数据。TCP连接上只有一个字节可以作为带外数据发送。
- MSG_PEEK:本标志适用于recv和recvfrom,表示只是从系统缓冲区中读取内容,而不清除系统缓冲区的内容。这样下次读的时候,仍然是相同的内容。一般在有多个进程读写数据时能够使用这个标志。
- MSG_WAITALL:是recv函数的使用标志。它告知内核不要在尚未读入请求数目的字节之前让一个读操作返回。即使指定了MSG_WAITALL,如果发生下列情况之一:(a)捕获一个信号;(b)连接被终止;(c)套接字发生一个错误,相应的读函数仍有可能返回比所请求字节数要少的数据。
2. send解析
- sockfd:指定发送端套接字描述符。
- buff: 存放要发送数据的缓冲区
- nbytes: 实际要改善的数据的字节数
- flags: 一般设置为0
1) send先比较发送数据的长度nbytes和套接字sockfd的发送缓冲区的长度,如果nbytes > 套接字sockfd的发送缓冲区的长度, 该函数返回SOCKET_ERROR。
2) 如果nbtyes <= 套接字sockfd的发送缓冲区的长度,那么send先检查协议是否正在发送sockfd的发送缓冲区中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送sockfd的发送缓冲区中的数据或者sockfd的发送缓冲区中没有数据,那么send就比较sockfd的发送缓冲区的剩余空间和nbytes。
3) 如果 nbytes > 套接字sockfd的发送缓冲区剩余空间的长度,send就一起等待协议把套接字sockfd的发送缓冲区中的数据发送完。
4) 如果 nbytes < 套接字sockfd的发送缓冲区剩余空间大小,send就仅仅把buf中的数据copy到剩余空间里(注意:并不是send把套接字sockfd的发送缓冲区中的数据传到连接的另一端的,而是协议传送的。send仅仅是把buf中的数据copy到套接字sockfd的发送缓冲区的剩余空间里)。
5) 如果send函数copy成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果在等待协议传送数据时网络断开,send函数也返回SOCKET_ERROR。
6) send函数把buff中的数据成功copy到sockfd的发送缓冲区的剩余空间后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个socket函数就会返回SOCKET_ERROR(每一个除send的socket函数在执行的最开始总要先等待套接字的发送缓冲区中的数据被协议传递完毕才能继续,如果在等待时出现网络错误那么该socket函数就返回SOCKET_ERROR)。
7) 在unix系统下,如果send在等待协议传送数据时网络断开,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的处理是进程终止。
3.recv解析
- sockfd: 接收端套接字描述符
- buff: 用来存放recv函数接收到的数据的缓冲区
- nbytes: 指明buff的长度
- flags: 一般置为0
1) recv先等待sockfd的发送缓冲区的数据被协议传送完毕,如果协议在传送sock的发送缓冲区中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR。
2) 如果套接字sockfd的发送缓冲区中没有数据或者数据被协议成功发送完毕后,recv先检查套接字sockfd的接收缓冲区,如果sockfd的接收缓冲区中没有数据或者协议正在接收数据,那么recv就一起等待,直到把数据接收完毕。当协议把数据接收完毕,recv函数就把sockfd的接收缓冲区中的数据copy到buff中(注意:协议接收到的数据可能大于buff的长度,所以在这种情况下要调用几次recv函数才能把sockfd的接收缓冲区中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的)。
3) recv函数返回其实际copy的字节数,如果recv在copy时出错,那么它返回SOCKET_ERROR。如果recv函数在等待协议接收数据时网络中断了,那么它返回0。
4) 在unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用 recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。
UNIX网络编程——send与recv函数详解的更多相关文章
- linux内核中send与recv函数详解
Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...
- linux Socket send与recv函数详解
转自:http://www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html linux send与recv函数详解 1 #include ...
- UNIX网络编程-send、recv、sendto、recvfrom详解
send.recv和sendto.recvfrom,一般情况下,send.recv在TCP协议下使用,sendto.recvfrom在UDP协议下使用,也可以在TCP协议下使用,不过用的很少. 1.s ...
- send()和recv()函数详解
send()函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP连 ...
- UNIX网络编程——getsockname和getpeername函数
UNIX网络编程--getsockname和getpeername函数 来源:网络转载 http://www.educity.cn/linux/1241293.html 这两个函数或者 ...
- UNIX网络编程——UDP 的connect函数(改进版)
上一篇我们提到,除非套接字已连接,否则异步错误是不会返回到UDP套接字的.我们确实可以给UDP套接字调用connect,然而这样做的结果却与TCP连接大相径庭:没有三次握手.内核只是检查是否存在立即可 ...
- [转]Socket send函数和recv函数详解
1.send 函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP ...
- Socket send函数和recv函数详解
1.send 函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP ...
- unix网络编程之listen()详解
转自于:http://blog.csdn.net/ordeder/article/details/21551567 Unix网络编程描述如下: #include <sys/socket.h> ...
随机推荐
- ubuntu linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)
shmget int shmget(key_t key, size_t size, int flag); key: 标识符的规则 size:共享存储段的字节数 flag:读写的权限 返回值:成功返回共 ...
- java表达式类型的自动提升
当一个java算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生自动提升.Java定义如下的自动提升规则:1. 所有byte型.short型和char型将被提升到int型. 2. 整个 ...
- jquery datagrid添加冻结列等
frozenColumns:[[ { field: 'xh', checkbox: true }, { field: "CZ", title: "操作", wi ...
- Django笔记--视图
URLconf 在settings.py文件中通过ROOT_URLCONF指定根级url的配置 urlpatterns是一个url()实例的列表 一个url()对象包括: 正则表达式 视图函数 名称n ...
- 90. Subsets II(中等,编写代码有难度)
Given a collection of integers that might contain duplicates, nums, return all possible subsets. Not ...
- Ubuntu 16.04+.Net Core+Docker+Uginx安装部署
前言 最近公司的项目打算移植到.Net Core平台,所以调研了一下.Net Core在Linux下的安装部署.本篇文章会一步步的描述从安装到配置到部署的全部过程.在文章的结构和内容里,笔者借鉴了很多 ...
- 独立完成一个移动点餐wap后的小结
1.技术栈:vue vue-router vuex Mint-ui better-scroll; 2.实践总结: a.单页应用不重新渲染组件问题:组件在初次渲染后不会重新渲染,此时当从某个路径 ...
- 【python标准库模块二】random模块学习
random模块是用来生成随机数的模块 导入random模块 import random 生成一个0~1的随机数,浮点数 #随机生成一个0~1的随机数 print(random.random()) 生 ...
- 04_Struts2标签
1.通用标签: property标签: 用来输出值栈属性的值 如果value属性没有给出,ValueStack值栈栈顶对象的值被输出 许多情况下,EL表达式可以提供更简洁的语法 url标签: url方 ...
- 在查询语句中使用 NOLOCK 和 READPAST
对于非银行等严格要求事务的行业,搜索记录中出现或者不出现某条记录,都是在可容忍范围内,所以碰到死锁,应该首先考虑,我们业务逻辑是否能容忍出现或者不出现某些记录,而不是寻求对双方都加锁条件下如何解锁的问 ...