Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.58.108.102] |
|
Сообщ.
#1
,
|
|
|
Чтоб объяснить проблему приведу простой пример:
Пример #1K: (ns - сокет) ... ... char buf[1024]; int nbytes, len; for(;;) { nbytes = recv (ns, buf, sizeof (buf) - 1, 0); buf[nbytes] = '\0'; len = strlen (buf); cout << buf; if (buf[nbytes-1]=='\n' && buf[nbytes-2]=='\n') break; if (len < 1024) break; } ... ... В данном примере последовательность символов "\n\n" приводит к завершению приёма сообщения, так-же к завершению его приема приводит ситуация когда сообщение будет < 1024 cимволов, однако мне это не подходит. Например если клиент шлет не всё сообщение сразу (телнетом например) то прием обламываеться после первой части если она меньше чем 1024. Даже если я начну читать из сокета посимвольно то после завершения этой первой части опять сработает break. Можно конечно отбросить break и ждать/читать пока не появиться \n\n НО тогда возникает проблема: если вдруг произойдет ошибка на стороне клиента (или во время передачи данных) то сервер "\n\n" не получит никогда и процесс просто зависнет. В общем может кто-нибудь может что-то посоветовать? Заранее спасибо! Добавлено в : Задам даже более конкретный вопрос: можно ли как-то выставить таймаут для функции recv() ? |
Сообщ.
#2
,
|
|
|
Цитата Использовать в цикле poll или select с достаточно малым тайм-аутом и читать до получения требуемых данных или ошибки. Michail04, 7.02.04, 22:38 Задам даже более конкретный вопрос: можно ли как-то выставить таймаут для функции recv() Добавлено в : Считывание данных из сокета. Добавлено в : По ссылке, правда, под Win, но отклонения там небольшие. |
Сообщ.
#3
,
|
|
|
Цитата trainer,7.02.04, 23:56 Использовать в цикле poll или select с достаточно малым тайм-аутом и читать до получения требуемых данных или ошибки. Тогда вопрос по select. Нашел я в мане пример: Цитата #include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(void) { fd_set rfds; struct timeval tv; int retval; /* Ждем, пока на стандартном вводе (fd 0) что-нибудь появится. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Ждем не больше пяти секунд. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Не полагаемся на значение tv! */ if (retval) printf("Данные доступны.\n"); /* Теперь FD_ISSET(0, &rfds) вернет истинное значение. */ else printf("Данные не появились в течение пяти секунд.\n"); exit(0); } Так вот как мне вместо fd_set rfds заставить работать с дескриптором сокета? |
Сообщ.
#5
,
|
|
|
Пробую следующее и всегда вылетаю в timeout
Цитата ... ... int sel = 0; timeval r_timeout; fd_set fds; FD_ZERO(&fds); FD_SET(ns, &fds); // ns - сокет r_timeout.tv_sec = 0; r_timeout.tv_usec = 15000000; sel = select(0, &fds, NULL, NULL, &r_timeout); if(!sel) { cout << "Timeout\n"; return 0; } if(sel < 0) { cout << "Error\n"; return -1; } return1; p.s. прочитав man select и обнаружив строчку: n на единицу больше самого большого номера дескриптора из всех наборов. (n - первый аргумент) попробовал: Цитата ... sel = select(ns+1, &fds, NULL, NULL, &r_timeout); ... но это дает тот же результат Что я делаю не так? |
Сообщ.
#6
,
|
|
|
А если написать:
r_timeout.tv_sec = 15; r_timeout.tv_usec = 0; |
Сообщ.
#7
,
|
|
|
C
Цитата r_timeout.tv_sec = 15; r_timeout.tv_usec = 0; как ни странно заработало:-) Сэнкс! |