2015-06-09 4 views
1

Я работаю на сервере Программирование на C в среде Linux. В то же время может быть несколько клиентов, связанных с сервером. Это мой первый проект на сервере. Программирование и отсутствие большого опыта в многопоточности. Теперь я запрограммировал следующее для многопоточности.Многопоточный сервер в LInux

Я хочу получить представление о следующих пунктах.

1.Как много клиентов будет обрабатывать сервер?

2.will pthread_t thr; создать несколько потоков или мне нужно сделать что-то вроде pthread_t thr[X], чтобы создать X потоков?

3. Как я могу получить данные для каждого клиента в следующем коде?

4.Will pthread_create создайте новую копию *connection_handler для каждого подключенного нового клиента.

void dieWithError(char *errormsg); 

FILE *file; 


void *connection_handler(void *socket_desc) 
{ 
    //Get the socket descriptor 
    int sock = *(int*)socket_desc; 
    int read_size; 
    char *message , client_message[2000]; 



    //Receive a message from client 
    while((read_size = recv(sock , client_message , 2000 , 0)) > 0) 
    { 
     //end of string marker 
     client_message[read_size] = '\0'; 

      printf("%s",client_message); 
      fprintf(file,"%s", client_message); 


     //clear the message buffer 
     memset(client_message, 0, 2000); 
    } 

    if(read_size == 0) 
    { 
     puts("Client disconnected"); 
     fflush(stdout); 
    } 
    else if(read_size == -1) 
    { 
     perror("recv failed"); 
    } 

    return 0; 
} 




int main(int argc, char** argv) { 

    int sock_desc = 0, connfd = 0,listenfd =0; 
    struct sockaddr_in serv_addr; 
    int clntSock; 
    struct sockaddr_in echoClntAddr; 
    unsigned int clntLen; 
    char sendBuff[1025]; 
    char recvBuff[10025]; 
    int n = 0; 
    pthread_t thr; 



    sock_desc = socket(AF_INET, SOCK_STREAM, 0); 

    if(sock_desc < 0) 
     dieWithError("Unable to open Socket\n"); 

    memset(&serv_addr,0,sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET ; 
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv_addr.sin_port = htons(7024); 

    if(bind(sock_desc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
     dieWithError("bind failed\n"); 

    if(listen(sock_desc,3) < 0) 
     dieWithError("listen failed\n"); 

    file = fopen("testServer.txt", "w"); 


     clntSock = sizeof(struct sockaddr); 
     int i =0; 
     while((connfd = accept(sock_desc, (struct sockaddr *)&echoClntAddr,(socklen_t*)&clntSock))) 
    { 
     puts("Connection accepted"); 



     if(pthread_create(&thr, NULL , connection_handler , (void*) &connfd) < 0) 
     { 
      perror("could not create thread"); 
      return 1; 
     } 

     //Now join the thread , so that we dont terminate before the thread 
     //pthread_join(thread_id , NULL); 
     puts("Handler assigned"); 
    } 

    if (connfd < 0) 
    { 
     perror("accept failed"); 
     return 1; 
    } 

     return (EXIT_SUCCESS); 
} 

void dieWithError(char *errormsg){ 
    printf("%s", errormsg); 


} 
+1

У вас есть логическая ошибка, которая проявится, если два клиента подключатся одновременно ... У вас нет контроля над тем, когда поток действительно начинает работать, а это означает, что вы могли бы иметь такую ​​ситуацию: 1. Сначала созданный поток, но он не запускается. 2. Вы вызываете 'accept' во втором соединении и создаете его поток. 3. Сначала начинается поток * second *. 4. Первый поток запускается. Теперь, когда вы передаете указатель на одну и ту же переменную на оба потока, оба потока будут использовать один и тот же сокет. –

+0

ok u означает, что оба будут использовать один и тот же порт и не будут передавать соединение на эфемерный порт. –

+0

Нет, все равно будет два разных соединения, но есть шанс (небольшой, но все же шанс), что два или более потока получают один и тот же сокет. Он будет работать для небольших и простых тестовых примеров, но вы не можете передать указатель на одну переменную в реальном производственном коде, если вы ожидаете нескольких одновременных подключений. –

ответ

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

  2. E.g. pthread_t thr; - это единственная переменная, способная удерживать один поток. You может использовать для повторного использования для нескольких потоков, но затем вы теряете другие потоки, ведущие к утечке ресурсов. Вам, вероятно, нужен массив или список, если вы хотите несколько потоков.

  3. Структуры. Одна структура на поток, каждая структура содержит информацию о потоке (pthread_t), клиентский сокет и все остальное, необходимое как для основного потока, так и для потока обработки клиента.

  4. Номер connection_handler является функцией , будет существовать только один экземпляр функции в процессе в памяти, функции не копируются.

+0

pthread_t thr; pthread_create (& thr, NULL, connection_handler, (void *) & connfd) Я делаю это в своем программном обеспечении и обрабатывает несколько клиентов и отображает данные от каждого клиента. –

+0

В connection_handler (пункт 4.) в ответе Вы имеете в виду, что один экземпляр connection_handler будет использоваться всеми потоками. –

+0

@JuniorBillgates В памяти будет только одна копия функционального кода, однако будет несколько контекстов потоков, указывающих на одну и ту же функцию. –

Смежные вопросы