在C程序中跨套接字实现多线程时出现问题



我正在用C语言创建一个使用套接字和线程的客户端-服务器聊天程序,但在实现多线程时遇到了问题。我目前得到的是一个服务器,它使用套接字从客户端获取连接,目前正在运行,问题是当我尝试创建多个线程来处理发送和接收时。

当客户端成功连接到服务器套接字时,会在客户端中创建一个线程,该线程在到达客户端程序的main while循环之前处理接收消息"connected to server id:x"。

当客户端到达服务器时,会在服务器中创建一个线程来处理数据的发送。

它们似乎工作正常,但执行顺序让我着迷。当我将客户端连接到服务器时,我认为会发生的事情是,为接收来自服务器的消息而创建的线程会执行,然后执行main while循环。但是看起来线程正在等待主循环接受输入。

// CURRENT CLIENT CODE - only including threading code
void * client_receive(void * sockID) {
int network_socket = *((int *) sockID);
while(1) {
char data[1024];
recv(network_socket, data, 1024, 0);
printf("%s", data);
}
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, client_receive, (void *) &network_socket);
while(1) {
printf("type a message: ");
scanf("%s", message);
send(network_socket, message, 1024, 0);
}
}
________________________________________________________________________________
// CURRENT SERVER CODE
struct client {
int index;
int sockID;
struct sockaddr_in clientAddr;
int len;
};
void * client_interact(void * client_detail) {
struct client* client_Detail = (struct client*) client_detail;
int index = client_Detail -> index;
int clientSocket = client_Detail -> sockID;
index = index + 1;
printf("Client connected");
char message[1024] = "Welcome!";
send(clientSocket, message, 1024, 0);
while(1) {
char receive[1024];
recv(clientSocket, &receive, 1024, 0);
printf("Client: %s", receive);
}
}
struct client Client[1024];
pthread_t thread[1024];
int main() {
while(1) {
pthread_create(&thread[client_count], NULL, client_interact, (void *) &Client[client_count]);
client_count++;
}
for (int i = 0; i < client_count; i++) {
pthread_join(thread[i], NULL);
}
return 0;
}

我是否误解了线程的执行?我认为在主打印"键入消息"之前,"client_receive"会在创建的线程上执行

main中的while循环之前,无法真正判断client_receive是否正在执行;这取决于调度程序。但是,在从套接字接收到一些数据之前,client_receive不会打印任何内容,因此,除非客户端向服务器发送一些数据,否则client_receive函数将阻止对recv的调用。

因此,虽然您的程序在运行client_receive之前似乎正在等待输入,但可能是client_receive正在阻塞对recv的调用,而您的主线程正在等待输入。

如果你的客户端实际上正在发送数据,而你的服务器似乎没有对这些数据做出响应,那么可能是你的客户端有某种缓冲。因此,请确保客户端的套接字flush强制将数据推送到服务器,从而调用recv


旁注:为了简洁起见,我假设您实际设置套接字连接并将句柄存储到network_socket中的代码没有包含在内,否则可能会有问题!

最新更新