I first use epoll to listen to the local socket_fd , if a non-local socket_fd triggers epoll , the socket_fd will be passed to a thread pool for processing.
The processing flow is like this.
- unlisten the socket_fd from epoll
- read the request (recv) from this socket_fd
- parse the request
- send a response
- read the request (recv) from this socket_fd
- ......
recv is "non-blocking" (ET), If recv returns a value less than 0 when reading the request, disconnect the socket_fd ( if the return value of recv is less than 0, it means that the client is no longer sending requests, so the connection is closed, close(socket_fd)).
Unlisten to socket_fd from the beginning because I don't want this socket_fd to trigger epoll_wait() when it resends a request, causing multiple threads to operate on one socket_fd (I want this socket_fd to be hosted by the assigned thread, But it seems that my fears are superfluous, because epoll works in ET).
This is what I don't understand, am I doing something wrong?
I don't know if it's because I have a problem with my thinking (a problem with the understanding of http 1.1 long connections)
The following code is the code to handle the client connection
void Handling_connections(int client_socket_fd)
{
//Remove the specified socket_fd from the monitoring queue of epoll
DEL_epoll_evs(client_socket);
for (; true; )
{
//Read the http header sent by the client
char* client_header_cstr = new char[1024];
memset(client_header_cstr, 0, 1024);
int read_size = recv(client_socket_fd, client_header_cstr, 1024);
//Disconnect the client if the content read is empty
if (read_size < 1)
{
std::cout << "Client disconnection \n\n\n";
close(client_socket_fd);
return;
}
//Ensure that the read http header is complete
std::string client_header(client_header_cstr);
for (; read_size == 1024; )
{
memset(client_header_cstr, 0, 1024);
read_size = read(client_socket_fd, client_header_cstr, 1024);
client_header += client_header_cstr;
}
delete[](client_header_cstr);
//http_header is an object I wrote to parse the http header
//it just parses the http header
http_header tmp_header(client_header);
//write_client sends the data to the client via the parsed http header
//and it does not disconnect the client regardless of the success of the transmission.
write_client(tmp_header);
//I thought the return value of the next recv was less than 0,
//because the interval between re-reading the data and the last data sent was too short
//(the client did not receive the data yet, and the server started reading the request message again),
//so I tried to do a short wait (100ms) before the next recv request message,
//but there was no difference with the previous result (the return value of the next recv was less than 0)
//
//std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
I thought I could use one tcp connection to handle multiple requests, but every time I finished sending data and re-fetching the socket_fd data, the return value of recv would be less than 0(It's as if the client is no longer sending requests, But sometimes, multiple requests can reuse this one socket connection, maybe 3 out of 50 requests.), causing the connection to be disconnected(just like http 1.0).