【问题标题】:c++ socket recv function loopc++ socket recv函数循环
【发布时间】:2015-03-24 10:57:09
【问题描述】:

我试图在 tcp 套接字上背靠背发送和接收 2 个数据。协议写在下面。

  1. 客户端发送数据
  2. 在接收到服务器上的数据时,它会发回给客户端

现在使用下面的客户端代码我无法获得第二个数据,我认为“Recv”函数做错了。下面是代码sn-p。

int Recv(char* buffer, int size) 
{
  int total = 0, n = 0;
  while((n = ::recv(m_hSocket, buffer+total, size-total-1, 0)) > 0) 
  {
    total += n;
  }
  buffer[total] = 0;
  return total;
}

int SendAndReceiveData()
{
  //CStringA cstData :: this data getting filled by some other code. Ignore!

  //Send data
  char chSendBuff[256];
  memset(chSendBuff, 0, sizeof(chSendBuff));
  sprintf_s(chSendBuff, sizeof(chSendBuff), "%s", (LPCTSTR)cstData);
  send(m_hSocket, chSendBuff, (int)strlen(chSendBuff), 0);

  //Read response
  char chRecvBuff[256];
  memset(chRecvBuff, 0, sizeof(chRecvBuff));
  int iRet = Recv(chRecvBuff, 256);
}

【问题讨论】:

  • 您可以使用char chSendBuff[256] = {}; 将数组归零。
  • 您不需要将接收到的缓冲区归零 - 这是浪费时间,因为无论如何您都将覆盖该缓冲区。
  • 'Recv' 在收到 256 个字节或连接关闭之前不会返回。你每次都发送 256 个字节吗?如果不是,客户端发送少后是否关闭连接?此外,'memset(chSendBuff, 0, sizeof(chSendBuff));':货物崇拜。您正在使用下一行中的 sprintf_s() 使用保证的以 null 结尾的字符串加载缓冲区。
  • @MaximEgorushkin 是的。不幸的是,网络上有几个客户端/服务器示例带有这些垃圾和开发人员。几十年来一直在盲目地复制 memset/bzero,(通常会忽略 recv 返回的结果)。

标签: c++ sockets


【解决方案1】:

您的接收函数应如下所示:

int receive(int sockfd, void *buf, size_t len, int flags)
{
    size_t toread = len;
    char  *bufptr = (char*) buf;

    while (toread > 0)
    {
        ssize_t rsz = recv(sockfd, bufptr, toread, flags);
        if (rsz <= 0)
            return rsz;  /* Error or other end closed connection */

        toread -= rsz;  /* Read less next time */
        bufptr += rsz;  /* Next buffer position to read into */
    }

    return len;
}

【讨论】:

    猜你喜欢
    • 2015-03-09
    • 2020-07-25
    • 2018-12-21
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 2020-09-01
    • 2013-12-13
    相关资源
    最近更新 更多