我的问题与以下代码有关:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <pthread.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int connections[100];
int connectionCounter = 0;
pthread_t clientHandlerThread;
void *ClientHandlerThread(void *index) {
int id = *reinterpret_cast<int*>(index);
char buffer[256];
while(true) {
recv(connections[id-1], buffer, sizeof(buffer), 0);
for(int i = 0; i < connectionCounter; i++) {
if(i == (id-1))
continue;
send(connections[i], buffer, sizeof(buffer), 0);
}
}
}
int main() {
sockaddr_in addr;
int addrlen = sizeof(addr);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(1111);
addr.sin_family = AF_INET;
int sListen = socket(AF_INET, SOCK_STREAM, 0);
bind(sListen, (sockaddr*)&addr, addrlen);
listen(sListen, SOMAXCONN);
int newConnection;
for (int i = 0; i < 100; i++) {
newConnection = accept(sListen, (sockaddr*)&addr, (socklen_t*)&addrlen);
if (newConnection == 0) {
std::cout << "Failed to accept the client's connection." << std::endl;
}
else {
char MOTD[256] = "Welcome! This is the Message of the Day.";
send(newConnection, MOTD, sizeof(MOTD), 0);
connections[i] = newConnection;
connectionCounter++;
pthread_create(&clientHandlerThread, NULL, ClientHandlerThread, (void*)&i);
}
}
return 0;
}
这只是一个简单的 TCP 服务器(这只是一个了解 Linux 下套接字的测试项目,因为它们在 Windows 下是不同的)这给我带来了很大的问题,尽管这也可以是一个简单的理解问题。
我的问题:我启动服务器(使用 G++、Debian Stretch 64 位、g++ main.cpp -o server -lpthread 编译)并连接到 2 个客户端。到目前为止有效,但我只能从一个客户端发送消息,而不能从另一个客户端发送消息。我在“ClientHandlerThread”函数中发现了问题。参数“index”被转换为一个 int,但它会递增 +1。这意味着我的 ID 不是 1(它应该是,因为只有 2 个客户端并且它以 0 开头)而是 2。
我的理解有问题吗?我刚开始在 Linux 下编写 C++,可能是我的线程有问题。
感谢您的帮助!
最佳答案
您将指向同一个变量的指针传递给所有 线程。如果您足够快地连接两个(或更多客户端),则两个或更多线程可以从该指针的取消引用中获得相同的值。
这是通常认为可以将整数值转换为指针并返回的极少数情况之一。
首先在调用 pthread_create
时使用 (void *) (intptr_t) i
。然后在线程函数中执行int id = (int) (intptr_t) index
。
或者,由于您使用 C++ 编程,您可以使用 std::thread
相反,它允许您按值传递参数。
关于C++ - 线程参数无缘无故地增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48167442/