send+recv注意事项


send

函数原型

  • ssize_t send( SOCKET s, const char *buf, size_t len, int flags )

注意事项

  • 待发送数据长度data_len
  • 套接字s的发送缓冲长度buf_len
  • 发送缓冲区剩余空间space_len
if(data_len > buf_len)
    return SOCKET_ERROR
else{
    if(协议正在发s缓冲中的数据)
      等待发送完成
    else{
        if(data_len > space_len)
            等待协议把s的数据发送完
            //除send外的socket函数开始前都要等发送缓冲区清空
            if(发送时网络断开)
                return SOCKET_ERROR
        else
            if(把buf中的数据复制到剩余空间 == success)
                return 实际复制的字节数
                //此时数据还没由协议发送到另一端
                //等待传输时断网,调用send的进程会收到SIGPIPE
            else
                return SOCKET_ERROR
    }
}

recv

函数原型

ssize_t recv(int s, char *buf, size_t len, int flags)

注意事项

while(s发送缓冲区的数据正在被协议传输)
    if(网络错误)    return SOCKET_ERROR
while(s接收缓冲区没有数据 || 正在接数据)
    continue
if(复制s接收缓冲区数据到buf == success)
   if(在等待协议接收数据的时候网络中断)
       return 0
   else//大于buf的长度就要分多次接收了
       return 实际复制的字节数
else 
    return SOCKET_ERROR

汇总

  • 上面的过程只是为了揭示其中的注意事项,实际实现要复杂更多
  • 从上面的描述可以看出,接收和发送数据的主体都是协议,而不是send和recv
  • 所以才会有send成功了并不代表数据就真的发送到另一端的说法
原文地址:https://www.cnblogs.com/annsshadow/p/5845188.html