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