【问题标题】:how to receive binary data from recv winsock function如何从 recv winsock 函数接收二进制数据
【发布时间】:2016-08-10 07:06:03
【问题描述】:

我寻求如何使用winsock API的recv函数从HTTP请求中接收二进制数据。

我对 std::string 和 string.append() 没有任何问题 但我的程序不需要依赖。

有人知道如何仅使用 char* 缓冲区获得相同的结果吗?

    do {
      iRecv = recv(m_socket, recvBuffer, MAX_BUFFER, 0);

      if ( iRecv > 0 )
      {

        //Need to override std::string with pure WINAPI
        response.append(recvBuffer, iRecv);

        iResponseLength += iRecv;
        xZeroMemory(recvBuffer, MAX_BUFFER);

      }
    } while( iRecv > 0 );

【问题讨论】:

  • std::string 能够很好地保存二进制数据,但是您可能会发现使用std::vector<uint8_t> 更方便。

标签: c++ winapi winsock


【解决方案1】:

没有充分的理由不使用 STL 容器,因为它们是 C++ 的核心,因此它们将在每个 C++ 编译器中可用。

但是,为了回答您的问题,如果您出于任何原因需要避免使用它们,您可以执行以下操作:

int iResponseCapacity = MAX_BUFFER*5;
int iResponseLength = 0;
char *response = new char[iResponseCapacity];

do
{
      iRecv = recv(m_socket, recvBuffer, MAX_BUFFER, 0);
      if (iRecv <= 0) break;

      if ((iResponseLength + iRecv) > iResponseCapacity)
      {
          int iNewCapacity = iResponseCapacity + (MAX_BUFFER*5);
          char *newResponse = new char[iNewCapacity];
          memcpy(newResponse, response, iResponseLength);
          delete[] response;
          response = newResponse;
          iResponseCapacity = iNewCapacity;
      }

      memcpy(&response[iResponseLength], recvBuffer, iRecv);
      iResponseLength += iRecv;
}
while (true);

//...

delete[] response;

关键是每次response 缓冲区填充到最大容量时重新分配它。像 std::stringstd::vector 这样的 STL 容器会在内部为您处理这个问题。有很多算法可用于在重新分配时计算有效的增长增量以更好地最大化内存性能和使用率,上面只是一个简单的例子来展示这个想法。

【讨论】:

    【解决方案2】:
    int bytesRead, iRecv;
    char recvBuffer[MAX_BUFFER];
    
    bytesRead = 0;
    do {
      iRecv = recv(m_socket, recvBuffer + bytesRead, MAX_BUFFER - bytesRead, 0);
      if ( iRecv > 0 )
         bytesRead += iRecv;
    } while ((iRecv > 0) && (bytesRead < MAX_BUFFER));
    

    do 循环完成时:bytesRead 保存读取的字节数,数据在recvBuffer 中。如果iRecv 为零,则连接正常关闭。如果iRecv 小于零,则存在错误。如果iRecv 大于零,则缓冲区已满。

    【讨论】:

    • 谢谢,但我没有完全得到我的数据,我只收到了 MAX_BUFFER 的值。我想我必须复制 recvBuffer 的内容,同时还要动态增加接收器的大小。 ?
    • @Ett 只需根据需要多次调用此代码。或者使缓冲区更大。
    猜你喜欢
    • 2013-07-31
    • 2012-07-05
    • 2018-04-21
    • 2012-07-27
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多