简体   繁体   English

在 C 程序中跨 sockets 实现多线程时遇到问题

[英]Trouble implementing multi-threading across sockets in C program

I'm creating a client-server chat program in C using sockets and threads and having an issue implementing multi-threading.我正在使用 sockets 和线程在 C 中创建一个客户端-服务器聊天程序,并且在实现多线程时遇到问题。 What I have currently got is a server that takes connections from clients using sockets that is working so far, the issue is when I try create multiple threads to handle sending and receiving.我目前得到的是一个服务器,它使用 sockets 从客户端获取连接,到目前为止它正在工作,问题是当我尝试创建多个线程来处理发送和接收时。

When a client successfully connects to the server socket a thread is created in the client that handles receiving a message 'connected to server id: x', before it reaches the main while loop of the client program.当客户端成功连接到服务器套接字时,会在客户端中创建一个线程来处理接收消息“已连接到服务器 id:x”,然后再到达客户端程序的主 while 循环。

When a client reaches the server, a thread is created in the server to handle sending that data.当客户端到达服务器时,会在服务器中创建一个线程来处理发送该数据。

They seem to work okay but its the order of execution that is getting me.他们似乎工作正常,但它的执行顺序让我着迷。 When I connect the client to the server what I thought would happen was the thread created to receive a message from the server would execute then the main while loop would.当我将客户端连接到服务器时,我认为会发生的是为从服务器接收消息而创建的线程将执行,然后主 while 循环将执行。 But instead it looks like the thread is waiting for main loop to take input.但是看起来线程正在等待主循环接受输入。

// 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;
}

Am I misunderstanding execution of threads?我误解了线程的执行吗? I thought that 'client_receive' would execute on the created thread before main printed 'type a message'我认为'client_receive'会在主打印'输入消息'之前在创建的线程上执行

It is not possible really to tell whether client_receive is being executed before the while loop in main ;无法真正判断client_receive是否在main中的while循环之前执行; that is up to the scheduler to decide.这由调度程序决定。 However, client_receive will not print anything until some data is received from the socket, so unless your client sends your server some data, the client_receive function will block on the call to recv .但是,在从套接字接收到一些数据之前, client_receive不会打印任何内容,因此除非您的客户端向您的服务器发送一些数据,否则client_receive function 将阻止对recv的调用。

Hence, while it may seem like your program is waiting for an input before running client_receive , it could be that client_receive is blocking on the call to recv and your main thread is waiting for input.因此,虽然您的程序在运行client_receive之前似乎正在等待输入,但可能是client_receive阻塞了对recv的调用,而您的主线程正在等待输入。

In the case where your client is actually sending data over and your server doesn't seem to be responding to that data, it could be that there's some sort of buffering on your client's side.如果您的客户端实际上正在发送数据并且您的服务器似乎没有响应该数据,则可能是您的客户端存在某种缓冲。 So make sure to flush your client's socket to force the data to be pushed to the server, causing recv to be called.因此,请确保flush客户端的套接字以强制将数据推送到服务器,从而调用recv


Side note: I'm assuming the code where you actually set up the socket connection and store the handle into network_socket has not been included for brevity, otherwise that could be an issue!旁注:为了简洁起见,我假设您实际设置套接字连接并将句柄存储到network_socket中的代码没有包括在内,否则这可能是一个问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM