Проблема реализации многопоточности через сокеты в программе на C - PullRequest
0 голосов
/ 25 октября 2019

Я создаю клиент-серверную программу чата на C, используя сокеты и потоки, и имею проблему с реализацией многопоточности. В настоящее время у меня есть сервер, который принимает соединения от клиентов с помощью сокетов, который работает до сих пор, проблема заключается в том, что я пытаюсь создать несколько потоков для обработки отправки и получения.

Когда клиент успешно подключается к сокету сервера, в клиенте создается поток, который обрабатывает получение сообщения «связано с идентификатором сервера: x», прежде чем оно достигнет основного цикла while клиентской программы.

Когда клиент достигает сервера, на сервере создается поток для обработки этих данных.

Кажется, они работают хорошо, но порядок исполнения меня заводит. Когда я подключал клиента к серверу, я думал, что произойдет поток, созданный для получения сообщения от сервера, тогда будет выполнен основной цикл 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" будет выполняться в созданном потоке, прежде чем основной печатный "введите сообщение"

1 Ответ

1 голос
/ 25 октября 2019

В действительности невозможно определить, выполняется ли client_receive перед циклом while в main;это решать планировщику. Однако client_receive не будет ничего печатать до тех пор, пока некоторые данные не будут получены из сокета, поэтому, если ваш клиент не отправит вашему серверу некоторые данные, функция client_receive заблокирует вызов на recv.

Следовательно, хотя может показаться, что ваша программа ожидает ввода перед запуском client_receive, возможно, client_receive блокирует вызов recv и ваш основной поток ожидает ввода.

В случае, когда ваш клиент на самом деле отправляет данные, а ваш сервер, похоже, не отвечает на эти данные, возможно, на стороне вашего клиента есть какая-то буферизация. Поэтому убедитесь, что flush сокет вашего клиента принудительно отправляет данные на сервер, вызывая recv.


Примечание: я предполагаю код, в котором вы на самом делеустановите сокетное соединение и сохраните дескриптор в network_socket для краткости не был включен, иначе это может быть проблемой!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...