Многопоточный сервер не может обрабатывать несколько клиентов - PullRequest
0 голосов
/ 27 мая 2018

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

Это сервер:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include<string.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<fcntl.h> //close
void *thread_function(void *arg);

int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[20000]="0";
int len=256;
int i=0;
char message[] = "Hello World";

int main() {
    int res;
    pthread_t a_thread;
    void *thread_result;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");

    for(;;){
        c = sizeof(struct sockaddr_in);
        //accept connection from an incoming client
        client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);

        if (client_sock < 0)
        {
            perror("accept failed");
            return 1;
        }
        puts("Connection accepted");
        printf("Client connected with IP: %s\n", inet_ntoa(client.sin_addr));


        pthread_create(&a_thread, NULL, thread_function, (void *)message);

        pthread_detach(a_thread);

    }
    //  return 0;
}
//-------------------------------------------------
//-------------------------------------------------
void *thread_function(void *arg) {
    //Receive a message from client
    while((read_size = recv(client_sock , client_message , 2000 ,0)) > 0 )
    {
        len=strlen(client_message);
        //Send the message back to client

        send(client_sock , client_message ,2000,0);
        fflush(stdin);
        fflush(stdout);
        puts(client_message);
        strncpy(client_message,"0",sizeof(client_message) - 1);
    }
}

А это клиент:

#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<fcntl.h> //close

int main(int argc , char *argv[])
{
    int n;
    char sn[200];
    int sock;
    struct sockaddr_in server;
    char message[2000] , server_reply[2000];
    int i=0;
    char user[20];
    char pass[20];
    int sig;
    //Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );

    //Connect to remote server
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        perror("connect failed. Error");
        return 1;
    }

    puts("Connected\n");

    //keep communicating with server
    n=1;
    while(1)
    {
        printf("Enter message : ");

        strncpy (message,"0",sizeof(message) - 1);
        // itoa(n, sn, 10);
        sprintf(sn, "%d", n);
        strcpy(message,sn);
        //gets(message);

        //Send some data
        send(sock , message , strlen(message) , 0);
        recv(sock , server_reply , 2000 , 0);
        puts("Server reply :");
        puts(server_reply);
        n++;
    }

    close(sock);
    return 0;
}

1 Ответ

0 голосов
/ 27 мая 2018

У вас есть только одна переменная client_sock, которая используется всеми потоками.Это означает, что каждый новый accept заменит эту переменную новым клиентским сокетом, так что практически все ваши потоки будут работать с одним (самым новым) сокетом, и ни один поток не будет обрабатывать ранее установленные сокеты.

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