如何在单独的线程中处理套接字请求,线程似乎阻塞了主进程



我正在尝试用C++创建一个简单的HTTP服务器。我希望在单独的线程中同时处理每个请求,但当我创建一个线程并在开始时放置一个简单的sleep(10)以造成一些延迟时,在第一个线程完成之前,无法向服务器发出另一个请求。我做错了什么?

这是我到目前为止的代码:

#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string>
#include <ostream>
#include <iostream>
#include <thread>
using namespace std;
void send_response (int socket)
{
sleep (10);
char buffer[2048] = {0};
int request = recv (socket, buffer, 2048, 0);
if (request == -1) {
perror ("error");
}
string message = "Hello from server";
string length = to_string (message.length ());
string hello = "HTTP/1.1 200 OKnContent-Type: text/plainnContent-Length: " + length + "nn" + message;
send (socket, hello.c_str (), hello.length (), 0);
close (socket);
}
int main(int argc, char const *argv[])
{
struct sockaddr_in address;
int opt = 1;
socklen_t addrlen = sizeof (address);
int server_fd = socket (AF_INET, SOCK_STREAM, 0);
if (server_fd == 0) {
perror ("socket failed");
exit (EXIT_FAILURE);
}
if (setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof (opt))) {
perror ("setsockopt");
exit (EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons (8080);
if (bind (server_fd, (struct sockaddr *)(&address), sizeof (address)) < 0) {
perror ("bind failed");
exit (EXIT_FAILURE);
}
if (listen (server_fd, 3) < 0) {
perror ("listen");
exit (EXIT_FAILURE);
}
while (true) {
int new_socket = accept (server_fd, (struct sockaddr *)(&address), &addrlen);
if (new_socket < 0) {
perror ("accept");
exit (EXIT_FAILURE);
}
thread response (&send_response, new_socket);
response.detach ();
cout << "request handled" << endl;
}
return 0;
}

我不需要等待线程完成或从线程返回任何数据,我只希望它开始,做一些工作,并将一些东西发送回客户端。我希望每个线程都能做大量的工作,这就是我使用睡眠的原因。

编辑:循环似乎已经准备好,正在等待第二个连接,并将成功接受新连接并创建一个新线程来处理它,但前提是第二次连接来自不同的IP地址。因此,如果我访问127.0.0.1:8080的服务器,并从不同的本地IP地址(如192.168.1.91(访问,两个连接都将通过同时运行的两个线程。然而,如果我简单地打开两个选项卡,都是127.0.0.1:8080,一次只接受一个连接,另一个将暂停。我似乎需要代码来处理来自同一IP地址的多个连接,但在谷歌上搜索这类问题并没有给我任何好的结果。

好吧,糟糕的是,一切都按预期进行。使用wget从同一IP发送多个请求会导致创建多个线程并同时处理这些请求。在Chrome中,出于某种原因,从同一IP打开多个选项卡会导致它们以串行方式发送,但在Firefox中,它们是并行发送的,同时到达并处理。这很奇怪,但我会把它归结为Chrome的一个奇怪之处。

最新更新