Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用套接字的http服务器响应_C++_Sockets_Http_Server - Fatal编程技术网

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

C++ 使用套接字的http服务器响应,c++,sockets,http,server,C++,Sockets,Http,Server,我的sockets服务器正在接收一个映像的GET请求,该映像为2MB,因此不适合单个发送(),这是我在第一次发送()中发送的内容: std::stringstream wsss; wsss 图像为2MB,因此无法在一次发送中使用() send()不能保证发送您要求发送的字节数。它可以发送更少的字节。它的返回值告诉您它实际接受发送的字节数。因此,您应该在循环中调用send(),直到所有字节都被接受。如果将此循环移动到它自己的可重用函数中,也将允许您发送图标数据,而无需首先将其复制到std::str

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

std::stringstream wsss;
wsss
图像为2MB,因此无法在一次发送中使用()

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@Wusevari:再仔细看看我的例子。我不会多次发送回复。只有一个响应被发送(并且可能只响应一个请求,因为您没有显示所有的服务器代码)。响应分为两部分(标题和图像)发送。代码在第一部分(标题)中循环,直到完全发送,然后在第二部分(图像)中循环,直到完全发送,然后停止发送(直到接收到下一个请求)。您显然不了解HTTP协议实际上是如何工作的,或者浏览器是如何请求数据的。从阅读开始。在服务器开始发送响应之前,浏览器不会知道图像的实际大小(即使如此,如果服务器选择以
分块
格式发送,浏览器也可能不知道-请参阅)。浏览器将愉快地坐在那里等待整个图像被接收,不管它有多大。。。。。。一旦响应开始,浏览器将继续读取,直到响应完成,不管需要多长时间。服务器负责在单个响应中从头到尾发送整个图像,除非浏览器另有要求。浏览器可以分段请求资源(通过
范围
请求头-请参阅),但在大多数情况下通常不会这样做。通常只有在将文件下载到用户的硬盘时,即使是在下载之后,通常也只恢复以前中断的下载。@Wusevari:我向您保证浏览器不是这样运行的,所以测试它没有意义。如果响应中存在
内容长度
标题,浏览器将继续读取,直到收到指定的字节数。HTTP就是专门为这种方式设计的。浏览器根据……中定义的规则确定响应的长度(以及请求数据的长度)。。。。。。TCP无法在一次
send()
中传输1TB的数据。如果图标大小为1TB,则
内容长度将为1TB,但需要在两侧进行多个
send()
/
recv()
调用才能实际发送/接收1TB的数据。浏览器不会发送多个
GET
请求来传输完整的图标。它将发送一个请求,接收一个1TB数据的响应,并读取完整的1TB数据(假设在响应完成之前套接字连接未断开)。
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) ...