2013-02-09 3 views
0

У меня возникли проблемы с моей клиентской версией программы чата клиентского сервера, где подключаются несколько клиентов. Проблема в том, что я сталкиваюсь с тем, как точно я должен отправлять (сообщение чата другому клиенту) и получать (сообщение чата от другого клиента) одновременно? Что происходит, так это то, что я всегда отправляю данные и никогда не читаю. Нужно ли мне разветвлять и читать один, а другой отправить?c socket: recv и отправка данных одновременно

здесь соответствующий код

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

while(1) { 

    fd_set rfds, wfds; 
    FD_ZERO(&rfds); 
    FD_ZERO(&wfds); 

    FD_SET(serverSocket, &rfds); 
    FD_SET(serverSocket, &wfds); 

    if(select(serverSocket+1, &rfds, &wfds, NULL, NULL) < 0) { 
     perror("select"); 
     exit(-1); 
    } 

    if (FD_ISSET(serverSocket, &rfds)) { 
    // we got data, read it 
    } 
    if (FD_ISSET(serverSocket, &wfds)) { 
    printf(">"); 

    // read keyboard 
    sendLen = 0; 
    while ((cmd[sendLen] = getchar()) != '\n') 
     sendLen++; 
    cmd[sendLen] = '\0'; 

    // send the data 
    } 
} 
+0

Не могли бы вы попробовать 2 разных потока для чтения и записи отдельно? – Ganesh

ответ

0

Вы должны поместить дескриптор файла 0 (стандартный ввод) в избранных, а, затем прочитать символы и буфер их, и когда сокет доступен для записи, скопируйте на него весь буфер. Таким образом, вы просто блокируете чтение на стандартном входе все время.

добавить

FD_SET(0, &rfds); 

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

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

while(read(0,buffer+filled,1)>0) {} 

Убедитесь поставить еще одно условие для выхода из цикла, если буфер заполнен.

то, когда вы можете написать в сокете отправить по почте размер вашего байта в вашем буфере, проверить, все ли оно написано или переместить байты остатков в начале буфера ,

В то время как (getchar()) блокирует вас, препятствуя вам получать какие-либо сообщения.

+0

Не могли бы вы подробно остановиться на этом, пожалуйста? – theStig

+0

Хорошо, так что он почти работает, кроме одной небольшой мелкой проблемы, которую нужно решить. Как-то мне нужно уведомить клиента, что им удобно набирать (обратите внимание на printf («>»)), но происходит то, что, поскольку в инструкции нет новой строки, она не выводится клиенту, пока клиент не обратится к возврату ключ. – theStig

+0

Вы можете сказать, что STDIN_FILENO будет немного более понятным, чем «0», когда вы имеете в виду stdin. –

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