2014-12-16 2 views
0

Я создал чат с клиентами и сервером, и все работает. Но у меня проблема печати. Проблема в том, что клиент может написать свое сообщение и одновременно прочитать сообщение от других клиентов. Поэтому я использовал поток, чтобы сделать оба одновременно. Он работает, но посмотрите на пример, в чем проблема:Как клиент может отправлять и получать сообщения одновременно с сокетами?

Здесь я начинаю писать мой первый messHere это получил сообщение, что прерывает мой writingAnd здесь я продолжаю писать

Я не знаю, если это clear: Я начинаю писать сообщение, но я его еще не отправил, потому что он не закончился, но в то же время получено сообщение, поэтому оно печатает его после начала моего письма и после того, как я могу продолжить писать.

У вас есть идея, как исправить эту проблему?

Вот код клиента:

void getMessage(char* message) { 
    size_t ln = -1; 
    while (ln <= 0 || ln > MESSAGE_MAX-1) { 
    printf(">"); 
    fgets(message, MESSAGE_MAX, stdin); 
    ln = strlen(message) - 1; 
    } 

    if (message[ln] == '\n') 
    message[ln] = '\0'; 
} 

void *thread_message(void *arg) 
{ 
    char* message; 
    message = malloc (sizeof(char) * MESSAGE_MAX); 
    int* sockfd = (int*)arg; 

    while (1) { 
    getMessage(message); 
    if (send(*sockfd, message, strlen(message), 0) == -1){ 
     perror("Client: send message"); 
    } 
    } 
    pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) 
{ 
    int sockfd, numbytes; 
    struct sockaddr_in their_addr; 
     // connector's address information 
    struct hostent *he; 
    char buf[MESSAGE_MAX + PSEUDO_MAX]; 

    // ... 
    } 

    while (1) { 
    if ((numbytes=recv(sockfd, buf, MESSAGE_MAX+PSEUDO_MAX, 0)) == -1) { 
     perror("Client: recv"); 
     return EXIT_FAILURE; 
    } 

    // ... 


     char* message; 
     message = malloc (sizeof(char) * MESSAGE_MAX); 

     // Here I launch the thread to write a message 
     pthread_t thread; 
     if (pthread_create(&thread, NULL, thread_message, &sockfd)) { 
     perror("pthread_create"); 
     return EXIT_FAILURE; 
     } 
    } 

    // Here I print the messages I receive 
    else 
    { 
     buf[numbytes] = '\0'; 
     printf("%s",buf); 
    } 

    } 

    close(sockfd); 
    return EXIT_SUCCESS; 
} 

Спасибо за вашу помощь! :)

+1

Почему вы печатаете полученные сообщения в том же буфере/местоположении сообщений, которые набирается локальным клиентом? –

+0

Потому что есть много клиентов. Таким образом, другие сообщения поступают от других клиентов и должны быть напечатаны: это чат между клиентами. – Danvdb

+1

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

ответ

0

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

Сказал, что, я считаю, что ваша проблема нить синхронизм.

  • Как резьбовые работы? В действительно упрощенном виде каждый поток будет иметь временной фрагмент для выполнения, а затем он даст пространство для других тем из вашей программы для выполнения. Вот почему вы должны использовать mutex для доступа к общей переменной, поэтому потоки не используют старые значения или перезаписывают данные.
  • Но как напечатать последовательно? Ну, вы можете использовать семафоры. Проверьте этот другой stackoverflow question. Проверьте Google на примерах на C, но этот пост дает вам базовые знания, чтобы справиться с этим.

:)

1

Один из способов решить проблему: возможно с помощью getch из ncurses. Сохраните то, что вы уже ввели в буфер. И отображать сообщения от других клиентов и вашего ввода в другой строке терминала.

Примечание: Я никогда не использовал libncurses раньше, но когда я вижу examples из ncurses, я знаю, что он может удовлетворить потребность в чат-программе. Надеюсь, это поможет.

+0

Я думаю, что это то, что я искал. Спасибо, я буду стараться. – Danvdb

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