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只有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。

  • 相关阅读:
    flask_第一个程序
    Web框架_MVC vs MVT
    python_使用qrcode生成二维码
    HDU 4641
    SPOJ NSUBSTR
    SPOJ LCS2 多个串的最长公共子串
    SPOJ LCS 后缀自动机找最大公共子串
    POJ 1509 循环同构的最小表示法
    HDU 4821 字符串hash
    SPOJ GSS1 静态区间求解最大子段和
  • 原文地址:https://www.cnblogs.com/-citywall123/p/12572801.html
Copyright © 2011-2022 走看看