2015-12-12 2 views
0

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

Проблема заключается в следующем: Клиент подключается к серверу без проблем; Поток (насколько я могу судить) создан без проблем; Но после того, как клиент пишет номер в сокете, сервер просто его не видит. Вызов read() не дает ошибок, он просто сидит там, ожидая всегда.

Я попытался отправить через него несколько целых чисел; нет разницы. У меня есть подозрение, что серверный дескриптор файла передается без проблем в поток, но я не могу понять, как это сделать. Еще одно подозрение в том, что я пропущу что-то глупое.

В любом случае, помощь приветствуется. Любые идеи?

Серверная сторона: цикл, который создает потоки.

while (1) { 

    int client; 

    printf("[server]Waiting at port %d...\n", PORT); 
    fflush(stdout); 

    int length = sizeof(from); 
    if (client = accept(sd, (struct sockaddr*)&from, &length) < 0) { 
     perror("[server]Error: accept()."); 
     continue; 
    } 

    pthread_t th_id; 
    pthread_create(&th_id, NULL, &treat, &client); 

    } 

Серверная сторона: функция обработки резьбы (проблема здесь).

void* treat(void* client) 
{ 

printf("[thread]Waiting for message...\n"); 
fflush(stdout); 
pthread_detach(pthread_self()); 

int client_sd = *((int*)client); 

int nr; 
if (read(client_sd, &nr, sizeof(int))) { 
    perror("[thread]Error: read()."); 
    exit(-1); 
} 
// The program won't reach this point. 
printf("[thread]Read: %d", nr); 
fflush(stdout); 

close(*((int*)client)); 
return (NULL); 

} 

стороне клиента:

 if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1) 
    { 
     perror ("[client]Error: connect().\n"); 
     return errno; 
    } 

    printf ("[client]Write a number: "); 
    fflush (stdout); 

    scanf("%d",&nr); 

    printf("[client] Read %d\n",nr); 

    if (write (sd,&nr,sizeof(int)) <= 0) 
    { 
     perror ("[client]Error: write()\n"); 
     return errno; 
    } 

    //the program reaches here. 
    printf("[client]The message was sent\n"); 
+0

Это: 'pthread_create (& th_id, NULL, & treat, & client);' может выйти из строя, если два клиента соединяются «одновременно». - «клиент» перезаписывается потоком accept() до того, как потоки сервера cient <> могут его прочитать, но это не похоже, что это основная проблема ATM. –

+0

Это не моя главная проблема, но это проблема; спасибо, что указали это. Я рассмотрю его после того, как я исправлю это. – Xebeq

+0

Я не вижу проблемы :(вызов read() должен возвращаться, и что-то должно быть напечатано. Возможно, это не так, как вы ожидаете, потому что вы не можете обработать результат, возвращенный read() правильно, но somethng должен быть напечатан: ( –

ответ

2

Проблема заключается в строке

if (client = accept(sd, (struct sockaddr*)&from, &length) < 0) { 

он интерпретируется как

if (client = (accept(sd, (struct sockaddr*)&from, &length) < 0)) { 

и если accept возвращает положительное, то client установлено на 0. Затем последующее чтение в потоке считывается из stdin.

+0

Ницца - будьте готовы! Я заметил, что, особенно, поскольку я всегда стонаю о разработчиках. неспособность разделить составные выражения во время отладки. –

+0

Кроме того, это не первый раз, когда я видел эту ошибку. Мне не кажется «естественным» использовать ошибочное выражение. Разумеется, я бы положил «client = accept()» на отдельную строку. Я подозреваю, что есть (еще один раз), какой-то сайт мусора с этим плохим кодом в качестве примера :( –

+0

Yup. Вы были правы. Сейчас работает отлично. Спасибо! – Xebeq

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