通过套接字正确发送 HTTP 响应
Properly sending HTTP response over sockets
我有一个套接字应用程序,并希望允许浏览器发送/接收数据。不幸的是,由于某种奇怪的原因,这段代码不适用于 Chrome,也不适用于 curl。奇怪的是,它似乎几乎可以很好地与Internet Explorer Edge一起使用,甚至可以在互联网上找到一些REST游乐场。
这可能是什么原因?我想假设这与标头有关,但是,我发送了与另一个域完全匹配的标头,但它仍然停滞不前。
似乎发生的事情是Chrome加载了数据,但是,停滞不前,并且从未收到官方回复 - 或者可能只是从未完成?我可以看到页面上的所有文本,但是,谷歌仍在加载,并且"服务器响应"报告它没有收到任何内容。除此之外,我认为它会向客户端发送两次相同的响应。
这是我的代码:
// sockserver.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <process.h>
#include <stdio.h>
#include <map>
#pragma comment(lib,"ws2_32.lib" )
unsigned int __stdcall ServClient(void *data);
int main(int argc, char* argv[])
{
WSADATA wsaData;
int iResult;
sockaddr_in addr;
SOCKET sock, client;
addr.sin_family = AF_INET;
addr.sin_port = htons(5900);
addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.22");
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);//2.2
if (iResult)
{
printf("WSA startup failed");
return 0;
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("Invalid socket");
return 0;
}
iResult = bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in));
if (iResult)
{
printf("bind failed %u", GetLastError());
return 0;
}
iResult = listen(sock, SOMAXCONN);
if (iResult)
{
printf("iResult failed %u", GetLastError());
return 0;
}
while (client = accept(sock, 0, 0))
{
if (client == INVALID_SOCKET)
{
printf("invalid client socket", GetLastError());
continue;
}
_beginthreadex(0, 0, ServClient, (void*)&client, 0, 0);
}
return 0;
}
std::map<int, SOCKET> sockList;
unsigned int __stdcall ServClient(void *data)
{
SOCKET* client = (SOCKET*)data;
SOCKET Client = *client;
printf("Client connectedn");
int xx = 0;
char chunk[200];
while (recv(Client, chunk, 200, 0))
{
char buf[] = "HTTP/1.1 200 OKnContent-Type: text/htmlnAccept: */*;Date:Sun, 21 Feb 2016 18:26:33 GMTnServer: ubersnipnContent-Length:18076nAccept-Encoding:gzip, deflate, sdchnAccept-Language:en-US,en;q=0.8nCache-Control:max-age=0nConnection:keep-alivenHost:localhost:2222nSet-Cookie:acct=t=t%2flE8KL9jDBOed05o1eMDiINlDfMvLxp&s=CUBOpXFMXmBt4u3pf%2fx5efr5WWkyGT3U; domain=.stackoverflow.com; expires=Sun, 21-Aug-2016 18:26:33 GMT; path=/; HttpOnlynn<html><body>Hello World</body></html>";
//sockList[sockList.size()] = Client;
send(Client, buf, strlen(buf), 0);
/*if (xx >= 1) {
closesocket(Client);
return 1;
}
else {
xx++;
}*/
printf("%s t %dn", chunk, GetCurrentThreadId());
}
return 0;
}
您正在设置 18076 的巨大内容长度,但您的内容要小得多。因此,浏览器将等待更多内容。但是,您不必提供更多内容,而只需等待浏览器发送另一个请求,因此客户端和服务器都在等待对方。
除此之外,您发送的许多标头都没有意义:接受,接受编码,接受语言和主机都是与请求相关的标头,在响应中没有意义。以HTTP结尾的正确行是rn
而不是n
尽管浏览器通常不关心这个细节。
似乎发生的事情是Chrome加载了数据,但是,停滞不前
正如你提到的,它"停滞",查看你的代码,你正在调用"recv",这是一个阻塞调用。如果没有可用数据,recv 将阻止。
这会是你拖延的地方吗?有一些 API 可用于检查是否有可用的数据,以允许您避免阻塞条件。只是提到这一点,以防它有帮助。
如果你进入了"send()",我怀疑你会停滞不前,但这也是可能的。
相关文章:
- HTTP 响应格式不正确?
- 使用 WinInet 修改/删除 HTTP 响应标头
- 如何在C++中使用 Curl 获取 HTTP 响应字符串
- QNetworkReply 如果 HTTP 响应类型为 201 CREATED,则返回空响应
- 如何从 HTTP 响应中删除垃圾数据
- 如何存储 http 响应并发送到浏览器
- Boost BEAST操纵HTTP响应标头持续接受
- 使用套接字编程的怪异HTTP响应
- C 从HTTP响应中获取图片
- HTTP响应标头是否可以不以状态行开头
- 使用字符串形成 HTTP 响应
- Webkit GTK:获取HTTP响应
- Recv 未返回足够的字节(二进制 http 响应)
- 无法接收HTTP响应正文C++
- 通过套接字正确发送 HTTP 响应
- 损坏的HTML - 浏览器不会从我的网络服务器下载整个HTTP响应,CURL可以
- 我如何从QNetworkReply读取内容(http响应体)
- NSMutableData to NSString -如何知道HTTP响应使用哪种编码
- 支持http 1.1响应缓存的c++库
- HTTP响应连接重置