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> ...
随机推荐
- [APIO2016]
2016的题貌似是韩国棒子出的,好丧啊.... 看了题解还想了好久...... ------------------------------------------------- A.Boat 有n个 ...
- Delphi 日期时间函数
DateUtils.IncYear();DateUtils.IncMonth();DateUtils.IncWeek();DateUtils.IncDay();DateUtils.IncHour(); ...
- c语言程序设计第四次作业——顺序结构
(一)改错题 输出三角形的面积和周长,输入三角形的三条边a.b.c,如果能构成一个三角形,输出面积area和周长perimeter(保留2位小数):否则,输出"These sides do ...
- 移动端开发,文字增加,字体自动放大(font boosting)
问题缘由:做文章详情页的时候,文字多了一点字体就放大了,真的是奇了怪了. 问题重现 一段文字的时候 两段文字的时候 很明显,字体放大了很多. 疑点 meta标签缩放的问题 最近正好遇到处理retain ...
- 借助Bodymovin播放svg动画
svg动画,截取工具有点不忍直视了~~~ 为了实现上面的svg动画,可以使用bodymovin插件,简单配置之后,就可以直接可以实现在 AE(可视化操作,不用码代码)上面导出 svg的json数据,在 ...
- 罗列Linux发行版的基础目录名称,命令法则和功能
罗列Linux发行版的基础目录名称命名法则及功用规定 目录描述 /主层次 的根,也是整个文件系统层次结构的根目录 /bin存放在单用户模式可用的必要命令二进制文件,所有用户都可用,如 cat.ls.c ...
- Docker学习系列(二)Docker初体验
一.系统要求 Docker的安装,需要在CentOS 7.0+版本,内核至少3.10,64-bit uname --r [randy@randysun ~]$ uname --r -.el7.x86_ ...
- ionic tab页面跳转
要使用到Tabs,现将Tabs导入 import { NavController, ModalController, Tabs } from 'ionic-angular'; 把要选择的Tabs页面的 ...
- 使用Docker搭建GitLab
使用docker-compose快速启动GitLab.(当然前提是你先安装docker-compose,安装方式见博客:http://blog.csdn.net/yulei_qq/article/de ...
- python3中替换python2中cmp函数的新函数分析(lt、le、eq、ne、ge、gt)
本文地址:http://blog.csdn.net/sushengmiyan/article/details/11332589 作者:sushengmiyan 在python2中我们经常会使用cmp函 ...