一般情况下:
send(),recv()用于TCP,sendto()及recvfrom()用于UDP

但是send(),recv()也可以用于UDP,sendto()及recvfrom()也可以用于TCP

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信号,进程对该信号的默认处理是进程终止。

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信号,进程对该信号的默认处理是进程终止。

sendto和recvfrom一般用于UDP协议中,但是如果在TCP中connect函数调用后也可以用.

sendto()和recvfrom()— —利用数据报方式进行数据传输  
  在无连接的数据报socket方式下,由于本地socket并没有与远端机器建立连接,所以在发送数据时应指明目的地址,sendto()函数原型为:  
  int sendto(int sockfd, const void *msg,int len unsigned int flags, const struct sockaddr *to, int tolen);  
  该函数比send()函数多了两个参数,to表示目地机的IP地址和端口号信息,而tolen常常被赋值为sizeof (struct sockaddr)。Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。  
  recvfrom()函数原型为:  
  int recvfrom(int sockfd,void *buf,int len,unsigned int lags,struct sockaddr *from,int *fromlen);  
  from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。fromlen常置为sizeof (struct sockaddr)。当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。Recvfrom()函数返回接收到的字节数或当出现错误时返回-1,并置相应的errno。  
  应注意的一点是,当你对于数据报socket调用了connect()函数时,你也可以利用send()和recv()进行数据传输,但该socket仍然是数据报socket,并且利用传输层的UDP服务。但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。

与recv()函数的比较:UDP使用recvfrom()函数接收数据,他类似于标准的read(),但是在recvfrom()函数中要指明目的地址。从套接字上接收一个消息。对于recvfrom ,可同时应用于面向连接的和无连接的套接字。recv一般只用在面向连接的套接字,几乎等同于recvfrom,只要将recvfrom的第五个参数设置NULL。不管是recv还是recvfrom,都有两种模式,阻塞和非阻塞,可以通过ioctl函数来设置。阻塞模式是一直等待直到有数据到达,非阻塞模式是立即返回,需要通过消息,异步事件等来查询完成状态。

本文转载于:http://blog.csdn.net/xvd217/article/details/38902081

腾讯面试题
Linux Socket TCP Recv的返回值>0是表示从接收缓冲区实际Copy了这么多个字节的数据出来,也就是表示系统已实际收到发送方发过来的这么多个数据或者更多的数据.返回值为0则表示服务器已主动断开连接,也就是已收到了服务器发过来的Fin或者Rst.若返回值等于-1的话,且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN),则表示接收缓冲区已无数据可读,但连接是正常的,可以稍后再尝试读.否则表示连接发生异常,连接已断开,无效描述符之类的.
 
Linux Socket TCP Send的返回值>0是表示已经发送了的字节数(未被确认的),例如要发送10个字节,在异步模式下返回值为5个字节,则表示已经Copy了5个字节到发送缓冲区,系统随后会发送这些数据,但这5个字节是未被确认的,也就是还没收到接收方的Ack,如果服务器无回应或网络断开,那么系统将会不断重发该数据包,直到收到这5个字节的Ack.而剩下的5个未发的字节则由应用程序调用Send再发.若返回值为0则表示服务器已主动断开连接,也就是已收到了服务器发过来的Fin或者Rst.若返回值等于-1的话,并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN),则表示系统在忙或者发送缓冲区已满了,但连接是正常的,可以稍后再尝试发.否则表示连接发生异常,连接已断开,无效描述符之类的.
 
UDP的sendto对应着recvfrom,一发一收.如果sendto的数据大于MTU,则会在IP层分片发送,到达目标后由IP层重组,再从recvfrom一次性返回.如果使用IP层分片重组则存在乱序,丢包,重包的问题.调用一次sendto,只要数据长度小于MTU都会以一个独立的UDP包发送.recvfrom的接收大小必须大于或等于sendto时的是数据大小.更正确的说法应该是UDP的包单位是以IP层的包为单位的.

recv,recvfrom,send,sendto的更多相关文章

  1. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  2. 接口处理篇 accept bind connect atan2 htons inet_addr inet_aton inet_ntoa listen ntohl recv send sendto socket

    accept(接受socket连线) 相关函数 socket,bind,listen,connect 表头文件 #include<sys/types.h> #include<sys/ ...

  3. UNIX网络编程读书笔记:recv和send函数

    这两个函数类似于标准的read和write函数,不过需要一个额外的参数. #include <sys/socket.h> ssize_t recv(int sockfd, void *bu ...

  4. send, sendto, sendmsg - 从套接字发送消息

    概述 #include <sys/types.h> #include <sys/socket.h> int send(int s, const void *msg, size_ ...

  5. UNIX网络编程-recv、send、read、write之间的联系与区别

    1.read ----------------------------------------------------------------------- #include <unistd.h ...

  6. linux中read,write和recv,send的区别

    linux中read,write和recv,send的区别 1.recv和send函数提供了和read和write差不多的功能.但是他们提供了第四个参数来控制读写操作. int recv(int so ...

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

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

  8. UDP编程中client和server中使用recvfrom和sendto的区别

    client中:      sendto(sfd,buf,strlen(buf),0,(struct sockaddr *)&saddr,len);      recvfrom(sfd,buf ...

  9. 一种构造WEB服务器端recv和send接口阻塞现象的方法

    send阻塞 socket recv send接口阻塞,会导致服务器端不在响应客户端任何请求,所以一般情况, 会将socket设置为非阻塞状态, 但是有些场景,例如ssl_accept就需要使用阻塞的 ...

随机推荐

  1. vue知识总汇

    学前预备知识 ECMAScript简介和ES6的新增语法 Nodejs基础 webpack的介绍 babel简介 vue基础 vue基础

  2. 【Loadrunner】使用LR录制HTTPS协议的三种方法

    使用LR录制HTTPS协议的三种方法 一.最简单的方法:浏览器配置打开浏览器,安装证书,配置完成后直接用http协议录制即可(配置完成的标识就是打开网页,不显示安全提示) 二.LR配置修改操作步骤如下 ...

  3. sql server 碎片整理——DBCC SHOWCONTIG

    转自: 1.http://blog.sina.com.cn/s/blog_6d2675450101ks6i.html 2.http://www.cnblogs.com/CareySon/archive ...

  4. mysql 约束条件 auto_increment 自动增长目录

    mysql 约束条件 auto_increment 自动增长 mysql 约束条件 auto_increment 自动增长起始值 布长 起始偏移量 mysql 约束条件 auto_increment ...

  5. 循环链表的实现与操作(C语言实现)

    循环链表是还有一种形式的链式存贮结构.它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环. 循环链表的操作 1,循环链表的新操作 2, 获取当前游标指向的数据元素 3, 将游标重置指向链 ...

  6. SSH secure shell 权威指南(转载)

    本书是一本介绍通信安全的书籍,如果你想保障你的通信安全,本书能给你一个很好的解决方案.本书从ssh协议介绍起,到具体的开源实现和商业实现.但本书同时介绍开源实现和商业实现,给人感觉比较乱.注意:由于o ...

  7. PAT 1046 Shortest Distance[环形][比较]

    1046 Shortest Distance(20 分) The task is really simple: given N exits on a highway which forms a sim ...

  8. Smarty模板变量调节器

    Smarty模板变量调节器用法 在smarty里面,怎么修饰文本和变量呢?当然,你可以通过php函数处理文本,然后再通过assign()方法分配到模板,其实smarty提供了变量调节器能够很容易的处理 ...

  9. Learn2Rank

    Learning to rank 排序学习是推荐.搜索.广告的核心方法.排序结果的好坏很大程度影响用户体验.广告收入等.排序学习可以理解为机器学习中用户排序的方法,这里首先推荐一本微软亚洲研究院刘铁岩 ...

  10. hdu5057 分块处理,当数值大于数据范围时树状数组 真是巧 将大数据分为小数据来处理

    这题说的给了100000个数有100000次操作 询问 L和R 区间内 在D位上为P的个数,用树状数组存 要开[10][10][100000]的int 开不了但是能开 这么大的unsign short ...