Socket一次Recv接受的字节有限制么?

从套接字接收数据。 返回值是表示接收数据的字符串。 一次接收的最大数据量由bufsize指定。它默认为零。

注意为了最好地匹配硬件和网络现实,bufsize的值应该是2的相对较小的幂,例如4096。

经实际测试recv不同端口接收情况不同,当前我们默认为1024字节

大多数情况下为1448字节

TCP socket的buffer

每个TCP socket在内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式以及TCP的流量(拥塞)控制便是依赖于这两个独立的buffer以及buffer的填充状态。接收缓冲区把数据缓存入内核,应用进程一直没有调用recv()进行读取的话,此数据会一直缓存在相应socket的接收缓冲区内。再啰嗦一点,不管进程是否调用recv()读取socket,对端发来的数据都会经由内核接收并且缓存到socket的内核接收缓冲区之中。recv()所做的工作,就是把内核缓冲区中的数据拷贝到应用层用户的buffer里面,并返回,仅此而已。进程调用send()发送的数据的时候,最简单情况(也是一般情况),将数据拷贝进入socket的内核发送缓冲区之中,然后send便会在上层返回。换句话说,send()返回之时,数据不一定会发送到对端去(和write写文件有点类似),send()仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer中,发送是TCP的事情,和send其实没有太大关系。接收缓冲区被TCP用来缓存网络上来的数据,一直保存到应用进程读走为止。对于TCP,如果应用进程一直没有读取,接收缓冲区满了之后,发生的动作是:收端通知发端,接收窗口关闭(win=0)。这个便是滑动窗口的实现。保证TCP套接口接收缓冲区不会溢出,从而保证了TCP是可靠传输。因为对方不允许发出超过所通告窗口大小的数据。 这就是TCP的流量控制,如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方TCP将丢弃它。

send函数工作原理:
  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)

recv函数工作原理:

  源码解释:

接收来自socket缓冲区对字节数据,当缓冲区没有数据可取时,recv会一直处于阻塞状态,直到缓冲区至少又一个字节数据可取,或者远程端关闭,关闭远程端并读取所有数据后,返回空字符串.

recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,直到协议把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0 。
  对方优雅的关闭socket并不影响本地recv的正常接收数据;如果协议缓冲区内没有数据,recv返回0,指示对方关闭;如果协议缓冲区有数据,则返回对应数据(可能需要多次recv),在最后一次recv时,返回0,指示对方关闭。

要点:

在进行TCP协议传输的时候,要注意数据流传输的特点,recv和send不一定是一一对应的(一般情况下是一一对应),也就是说并不是send一次,就一定recv一次就接收完,有可能send一次,recv多次才接收完,也可能send多次,一次recv就接收完了。TCP协议会保证数据的有序完整的传输,但是如何去正确完整的处理每一条信息,是程序员的事情。
例如:服务器在循环recv,recv的缓冲区大小为100byte,客户端在循环send,每次send 6byte数据,则recv每次收到的数据可能为6byte,12byte,18byte,这是随机的,编程的时候注意正确的处理。

 

socket中send和recv函数的更多相关文章

  1. SOCKET中send和recv函数工作原理与注意点

    https://blog.csdn.net/rankun1/article/details/50488989

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

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

  3. socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题

    Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...

  4. linux Socket send与recv函数详解

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

  5. [转]socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题

    Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...

  6. 分片传输——send和recv函数

    最近在写socket编程收发数据,对于如何发送和接收大量数据,一直在思考.send和recv一般缓存区大小为4K,但是如果你要传输的数据超过了这个标准该如何做呢. 我想到的就是如改写write和rea ...

  7. socket函数send和recv函数

    转自:http://www.cppblog.com/aaxron/archive/2012/04/27/172891.html 在发送端,一次发送4092个字节,在接收端,一次接收4092个字节,但是 ...

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

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

  9. UNIX网络编程——send与recv函数详解

    #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); ssize_ ...

随机推荐

  1. 执行ng build --prod --aot命令报错

    D:\git\**\src\main\iui>ng build --prod --aotHash: 257ab60feca43633b6f7Time: 25358mschunk {0} poly ...

  2. 自动生成sql

    添加下面这个类 public static class GetAllAttribute<T> where T : class { public static string Names; p ...

  3. strust2的10种type类型

    <result-types> <result-type name="chain" class="com.opensymphony.xwork2.Acti ...

  4. windows服务器安装安全狗时服务名如何填写

    安全狗安装时“服务名”这一栏指的是apache进程的服务名称,即进入“任务管理-服务”里显示的名称. phpstudy等软件搭建的环境需要设置运行模式为“系统服务”后才能看到服务名.

  5. C++拾遗(五)——类

    类是 C++ 中最重要的特征.C++ 语言的早期版本被命名为“带类的 C(Cwith Classes)”,以强调类机制的中心作用.随着语言的演变,创建类的配套支持也在不断增加.语言设计的主要目标也变成 ...

  6. SPOJ SORTBIT Sorted bit squence (数位DP,入门)

    题意: 给出一个范围[m,n],按照二进制表示中的1的个数从小到大排序,若1的个数相同,则按照十进制大小排序.求排序后的第k个数.注意:m*n>=0. 思路: 也是看论文的.一开始也能想到是这种 ...

  7. 【Python图像特征的音乐序列生成】图像特征在旋律生成中有什么用

    jishude 首先援引一个资料网页:http://www.cosmosshadow.com/ml/%E5%BA%94%E7%94%A8/2016/03/01/%E9%9F%B3%E4%B9%90%E ...

  8. BZOJ 1396:识别子串 SA+树状数组+单调队列

    1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 381  Solved: 243[Submit][Status][Discuss] ...

  9. Visual Studio Professional 2015 简体中文专业版 序列号

    Visual Studio Professional 2015 简体中文专业版 专业版激活密钥:HMGNV-WCYXV-X7G9W-YCX63-B98R2 Visual Studio Enterpri ...

  10. Luogu [P3367] 模板 并查集

    [模板]并查集 题目详见:[[P3367][模板]并查集] (https://www.luogu.org/problemnew/show/P3367) 这是一道裸的并查集题目(要不然叫模板呢) 废话不 ...