我有一个多线程 HTTP TCP 服务器(用 Linux 编写),下面是处理客户端的函数:
void tcp_server::connection_handler(client* cl) {
// add client to the clients <vector>
mx.lock();
cl->set_id(static_cast<int>(clients.size()));
clients.push_back(*cl);
cout << "New client with id " << cl->get_id() << " has been added to the clients list" << endl << endl;
mx.unlock();
char read_buffer[1024];
ssize_t message_size;
string received_message;
while (accept_connections) {
memset(&read_buffer, 0, sizeof(read_buffer));
received_message.clear();
message_size = recv(cl->sock, read_buffer, sizeof(read_buffer) - 1, 0);
if (message_size == 0) {
// client disconnected
cout << "Client with id " << cl->get_id() << " has been disconnected" << endl;
close(cl->sock);
//remove client from the clients <vector>
mx.lock();
int client_index = find_client_index(cl);
clients.erase(clients.begin() + client_index);
cout << "Client with id " << cl->get_id() << " has been removed from the clients list" << endl;
mx.unlock();
delete cl;
break;
}
if (message_size == -1) {
if (!accept_connections) {
cerr << "Unable to receive message from client with id " << cl->get_id() << ". Server has been shut down. Stop receiving messages from this client" << endl;
}
else {
cerr << "Error while receiving message from client with id " << cl->get_id() << endl;
}
cerr << strerror(errno) << endl;
}
else {
//message was received succesfully
cout << "[Server] Client's message has been received" << endl;
cout << "[Server] Client's message: " << endl;
cout << "----------------------------" << endl;
cout << read_buffer << endl;
cout << "----------------------------" << endl;
for (unsigned int i = 0; i < message_size; i++) {
received_message.push_back(read_buffer[i]);
}
string response_message = convert_client_message(received_message);
if (send(cl->sock, response_message.c_str(), response_message.size(), 0) == -1) {
cout << "[Server] Message sending to client with id " << cl->get_id() << " failed" << endl;
}
cout << "[Server] Server's response: " << endl;
cout << "----------------------------" << endl;
cout << response_message << endl;
cout << "----------------------------" << endl << endl;
cout << "[Server] Message has been sent to client" << endl << endl;
cout << "============================" << endl << endl;
}
}
}
你怎么看,有一个缓冲区,里面包含客户端的消息,只有 1024 字节,而请求可以大于 1024 字节。 所以,问题是:我需要知道请求是否被完全接收。 我正在考虑编写可能会告诉我是否收到完整请求的解析器,但我真的不知道如何检测完整请求。
最佳答案
I was thinking about writing parser that might tell me if a full request was received, but I don't really know how to detect full request.
在实现协议(protocol)时,建议实际仔细查看协议(protocol)的规范。
如果您阅读 HTTP 1.1 specification ,你会发现每个 HTTP message由标题和可选的正文组成。一旦您阅读了请求 header 和可选正文,该请求就被完整阅读了。 header 以空行 \r\n
序列结尾。某些 HTTP 方法,如 POST
,可能有主体,在这种情况下,您将在 Content-Length
header 中找到主体的长度,或者您必须处理与 chunked transfer encoding .
请研究规范以获取更多详细信息。
关于c++ - 我如何知道请求是否完全使用 TCP 套接字接收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50956504/