使用套接字的http服务器响应

时间:2016-04-25 20:34:31

标签: c++ sockets http server

我的套接字服务器正在接收图像的GET请求,图像为2MB,因此它不适合单个send(),这是我在第一个send()中发送的内容:

std::stringstream wsss;
wsss << "HTTP/1.1 200 OK\r\n" 
     << "Connection: keep-alive\r\n"
     << "Content-Type: image/x-icon\r\n"
     << "Content-Length: " << imageSize << "\r\n"
     << "\r\n";
wsss.write(imageData, imageSize);

此图像的每个后续发送()是否都需要标题字段? 我发送.ico图像,标题字段是否正确?

1 个答案:

答案 0 :(得分:3)

  

图像为2MB,因此它不适合单个send()

send()无法保证发送您要求发送的字节数。它可以发送更少的字节。它的返回值告诉你实际接受发送的字节数。因此,您应该在循环中调用send(),直到所有字节都被接受为止。如果您将此循环移动到其自己的可重用功能中,那么您还可以发送图标数据,而无需先将其复制到std::stringstream

尝试这样的事情:

int sendData(int sckt, void *data, int datalen)
{
    unsigned char *pdata = (unsigned char *) data;
    int numSent;

    // send() can send fewer bytes than requested,
    // so call it in a loop until the specified data
    // has been sent in full...

    while (datalen > 0) {
      numSent = send(sckt, pdata, datalen, 0);
      if (numSent == -1) return -1;
      pdata += numSent;
      datalen -= numSent;
    }

    return 0;
}

std::stringstream wsss;
wsss << "HTTP/1.1 200 OK\r\n" 
     << "Connection: keep-alive\r\n"
     << "Content-Type: image/x-icon\r\n"
     << "Content-Length: " << imageSize << "\r\n"
     << "\r\n";

// do not append the image data to the stringstream...
//wsss.write(imageData, imageSize);

// send the headers first...
std::string headers = wsss.str();
int res = sendData(TheSocket, headers.c_str(), headers.size());
if (res == -1) ...

// now send the image data...
res = sendData(TheSocket, imageData, imageSize);
if (res == -1) ...
  

此图像的每个后续发送()是否都需要标题字段?

每个 HTTP响应到同一图像的每个 HTTP请求需要发送相同的标头 1 。但任何特定响应的每个send() 都不需要重复标题,只需要发送一次。只需继续发送尚未发送的字节。这就是为什么你必须注意send()的返回值,这样你就知道到目前为止已经发送了多少字节,还需要发送多少字节。

  

我发送.ico图片,标题字段是否正确?

一般来说,是 1

1 假设

  1. 客户端发送了一个没有Connection: close请求标头的HTTP 1.1请求。

  2. 客户端发送了带有Connection: keep-alive请求标头的HTTP 1.0请求。

  3. 否则,您的Connection: keep-alive标头将是错误的,您应该发送Connection: close标头,然后在发送完整响应后关闭套接字。