gpt4 book ai didi

c++ - 服务器多线程无法保存最后的套接字描述符

转载 作者:行者123 更新时间:2023-11-30 05:33:54 25 4
gpt4 key购买 nike

我有一个使用线程的项目。问题是,每次特定客户端发送消息时,它只保存最后一个 client_sock,这样我就无法保存前一个线程的调用,因为我从任何客户端发送的每条消息都会回答我最后一个的答案已创建的客户端,意味着以前的客户端已被覆盖。

class ServerTcp {
private:
pthread_t threads[50];

这是创建线程的函数,它正在发送到 recieveAndSend:

void ServerTcp:: acceptTheReaquest(){
struct sockaddr_in client_sin;
unsigned int addr_len = sizeof(client_sin);
int sockFd;
while((sockFd = accept(this->sock, (struct sockaddr *) &client_sin,
&addr_len)) >= 0){
struct arg_struct args; //has only 2 values, initialized in next lines
args.client_sock = sockFd;
args.server = this;
cout << "created " << sockFd << endl;
pthread_create(&threads[numOfThreads],NULL,
&ServerTcp::recieveAndSend, &args);
numOfThreads++;
}
}

这是接收和发送函数:

static void* ServerTcp:: recieveAndSend(void * args){
arg_struct* arguments = static_cast<arg_struct*>(args);
char buffer[4096];
while (true){
memset(&buffer, 0, sizeof(buffer));
int bytes = arguments->server->recieveFromClient(buffer,
arguments->client_sock);
if (bytes >0){
string message = arguments->server->reciveOutput(buffer);
arguments->server->sendTO(message, arguments->client_sock);
}
}
return (void*)NULL;
}

这是函数 sendTo:

void ServerTcp:: sendTO(string answer, int client_sock){
cout << "sending to " << client_sock << endl;
char buffer[4096];
strcpy(buffer, answer.c_str());
this->sent_bytes = send(client_sock, buffer, sizeof(buffer), 0);
}

输出:

created 4
received from 4
created 5
received from 5

这意味着我已经为 client_sock 4 创建了一个线程,并等待从 client_sock 4 接收,对于 client_sock 5 也是如此。现在我希望服务器打印发送到 4,从 4 接收 - 因为我使用了客户端client_sock 4 这是第一个创建的,也是我发送消息的那个,但它仍然持有 client_sock 5,输出是:

sending to 5
received from 5

代替

sending to 4
received from 4

.....帮助??

最佳答案

你的代码中的错误如下(我已经删除了不相关的代码行,并清理了缩进):

while((sockFd = accept(this->sock,  (struct sockaddr *) &client_sin, &addr_len)) >= 0)
{
struct arg_struct args;
args.client_sock = sockFd;
args.server = this;

pthread_create(&threads[numOfThreads],NULL,
&ServerTcp::recieveAndSend, &args);
numOfThreads++;
}

您正在堆栈上的局部范围内实例化 arg_struct。然后将指向 arg_struct 的指针传递给新线程。

这里的问题是父线程中pthread_create()返回后,循环终止(好吧,循环当前迭代终止,又重新开始),而arg_struct是no更长的有效期。

但是,子线程将尝试通过它从 pthread_create() 接收到的指针独立访问它,这将导致未定义的行为。

您观察到的行为是这种未定义行为的结果(父线程将在堆栈上为第二个线程在相同的原始内存位置实例化一个新的 arg_struct,但是当第一个线程醒来时,它仍然会在相同的位置查找)。

您需要做的是在堆上构造arg_struct,使用new 运算符。这样,对于新线程,实例化的 arg_struct 将继续存在。当然,新线程负责在完成后删除arg_struct,以避免内存泄漏。

关于c++ - 服务器多线程无法保存最后的套接字描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34533028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com