#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函数详解的更多相关文章

  1. linux内核中send与recv函数详解

    Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...

  2. linux Socket send与recv函数详解

    转自:http://www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html linux send与recv函数详解   1 #include ...

  3. UNIX网络编程-send、recv、sendto、recvfrom详解

    send.recv和sendto.recvfrom,一般情况下,send.recv在TCP协议下使用,sendto.recvfrom在UDP协议下使用,也可以在TCP协议下使用,不过用的很少. 1.s ...

  4. send()和recv()函数详解

    send()函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP连 ...

  5. UNIX网络编程——getsockname和getpeername函数

    UNIX网络编程--getsockname和getpeername函数   来源:网络转载   http://www.educity.cn/linux/1241293.html     这两个函数或者 ...

  6. UNIX网络编程——UDP 的connect函数(改进版)

    上一篇我们提到,除非套接字已连接,否则异步错误是不会返回到UDP套接字的.我们确实可以给UDP套接字调用connect,然而这样做的结果却与TCP连接大相径庭:没有三次握手.内核只是检查是否存在立即可 ...

  7. [转]Socket send函数和recv函数详解

    1.send 函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP ...

  8. Socket send函数和recv函数详解

    1.send 函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP ...

  9. unix网络编程之listen()详解

    转自于:http://blog.csdn.net/ordeder/article/details/21551567 Unix网络编程描述如下: #include <sys/socket.h> ...

随机推荐

  1. Python中set的功能介绍

    Set的功能介绍 1.集合的两种函数(方法) 1. 集合的内置函数 交集 格式:x.__and__(y)等同于x&y 例如:s1 = {'a',1,} s2 = {'b',1,} s3 = { ...

  2. ThreadLocal基本原理及运用

    ThreadLocal提供本地线程变量.这个变量里面的值(通过get方法获取)是和其他线程分割开来的,变量的值只有当前线程能访问到,不像一般的类型比如Person,Student类型的变量,只要访问到 ...

  3. 微信内置浏览器 如何小窗不全屏播放视频?也可以尝试canvas.

    设置属性: <video height="100%" width="100%" autoplay="autoplay" control ...

  4. Mysql根据一个基库生成其他库与其不同的库升级脚本

    今天研究了一下不同数据库之间如何做同步.弄了一个升级工具类,希望以后还能有所帮助. public class UpgradeDataBase { public static void main(Str ...

  5. 罗列Linux发行版的基础目录名称,命令法则和功能

    罗列Linux发行版的基础目录名称命名法则及功用规定 目录描述 /主层次 的根,也是整个文件系统层次结构的根目录 /bin存放在单用户模式可用的必要命令二进制文件,所有用户都可用,如 cat.ls.c ...

  6. 03 持续集成和部署/基础设施 - DevOps之路

    02 持续集成和部署/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi 服务的持续集成和部署这里有两套 ...

  7. 导出数据子集:带where条件的exp导出

    举个例子:用select * from all_objects创建了一张表T.想要导出object_id小于5000的所有行.(1)windows下: exp userid=cms0929/cms09 ...

  8. myeclipse中修改maven的默认仓库位置

     1.本地需要安装Maven.这里假设安装在D:\Program Files\apache-maven-2.2.1       2.修改本地maven库的路径:在D:\Program Files\ap ...

  9. 自定义支持多行显示的RadioGroup

    自定义支持多行显示的RadioGroup 原生的RadioGroup继承自LinearLayout,即只能支持一横排或者一竖排的排列显示RadioButton 现在改写RadioGroup,使它支持多 ...

  10. GDAL库进度信息编写示例

    GDAL进度信息编写 GDAL库中的算法以及读写数据的时候一般都会提供两个与进度信息相关的参数,下面分别进行描述: GDALProgressFunc pfnProgress void * pProgr ...