我有一个多线程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字节。 因此,问题是:我需要知道请求是否已完全收到。 我当时正在考虑编写解析器,该解析器可能会告诉我是否收到了完整请求,但是我真的不知道如何检测完整请求。
答案 0 :(得分:4)
我当时正在考虑编写解析器,该解析器可以告诉我是否收到了完整的请求,但是我真的不知道如何检测完整的请求。
实施协议时,建议您仔细查看协议规范。
如果您阅读HTTP 1.1 specification,您将意识到每个HTTP message包含标题和可选的正文。阅读请求标头和可选主体后,请求将被完全读取。 标题以空行\r\n
序列结束。某些HTTP方法(例如POST
)可能具有主体,在这种情况下,您将在Content-Length
标头中找到主体的长度,或者必须处理chunked transfer encoding。
请研究规格以获取更多详细信息。