zoukankan      html  css  js  c++  java
  • 使用send()函数发送数据,系统如何知道数据发送成功

    函数作用

    我们知道,服务端中有一个接收缓存区,客户端中有一个发送缓存区,同时每个TCP socket在内核中也都有一个发送缓冲区和一个接收缓冲区,

    send()函数的作用就是将客户端或服务端中的数据拷贝到SOCKET的发送缓存区中

    recv()函数的作用就是将SOCKET的接收缓存区中数据拷贝到客户端或服务端的接收缓存区中

    综上,send()函数和recv()函数只完成应用层到传输层的数据搬运,并不直接将数据传送到数据的另一端去,真正完成数据的传输的是协议功能(TCP/UDP)

    函数参数

    ssize_t  send(int sockfd,  const void *buf,   size_t len,  int flags);

     

    sockfd:创建的sockfd文件描述符,

    buf:发送数据所在的数据区,

    len:发送数据的长度,

    flags:标志位默认设置为0

     

    send()函数的返回值

     

    1、成功执行时,返回发送的字节数。

     

    2、失败则返回SOCKET_ERROR

     

     

    ssize_t recv ( int sockfd,  void *buf,   size_t len,   int flags);

     

    recv()函数的返回值

    1、成功执行时,返回接收到的字节数。

    2、若另一端已关闭连接则返回0,这种关闭是对方主动且正常的关闭

    3、失败返回-1,errno被设为以下的某个值   

     

    如何判断数据是否发送成功?

    通过send()函数的返回值,应用层只知道数据是否“拷贝”成功,另一端是否接收数据成功仅靠send()函数的返回值是判断不了的,

    对方是否接收数据成功发送端是判断不了的,如果发送端需要知道接收端是否接收数据成功,需要接收端给发送端返回一个值来确定(应用层面确定数据发送成功)

    系统底层确定数据是否发送成功(协议层面确定数据发送成功)

    TCP协议会确保数据完整的发送出去,同时保证数据到达接收端的SOCKET接收缓存区

    TCP数据报首部包含发送数据包的基本信息,比如数据长度

    TCP协议的ACK确认机制

    当SOCKET发送缓存区的大小为0的时候,也可以确定数据完全发送出去,buffer.size()==0

    补充:

    1、滑动窗口在SOCKET的缓存区里面,窗口的大小会根据接收端的处理情况动态变化(保证SOCKET的接收缓冲区不会溢出)

    2、TCP 的SOCKET有接收缓存区和发送缓存区,而UDP的socket只有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。

  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/-citywall123/p/12572801.html
Copyright © 2011-2022 走看看