![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Recv и синхронный режим [D5]
Ivan K © (2004-06-14 15:09:00)Как узнать, пуст ли буфер? А то иначе при вызове Recv оно (в смысле Recv) ждет, пока в нем что-то будет и вешает прогу...
Ivan K (2004-06-20 15:17:00) [1]
Digitman
> Длина отклика не превышает 512 символов, включая CRLF.
>
Отклик-то может и менее 512 чимволов, а заголовок письма и более килобайта... Пример надо?
Digitman (2004-06-18 08:26:00) [2]замечание :
На практике многострочные отклики для исключения имитации завершаются последовательностью CRLF.CRLF.
т.е. признак конца отклика - прием строки '.'#10#13#10#13
Digitman (2004-06-18 08:25:00) [3]Сигнал отклика в POP3 содержит индикатор состояния и ключевое слово, за которым может следовать дополнительная информация. Отклик также завершается кодовой последовательностью CRLF. Длина отклика не превышает 512 символов, включая CRLF.
Отклики на некоторые команды могут содержать несколько строк. В этом случае последняя строка содержит код завершения 046 ("."), за которым следует CRLF.
отсюда следует, что вызывать recv() и накапливать принятые байты отклика следует до тех пор, пока не будет принята строка '.'#10#13
Ivan K (2004-06-17 23:19:00) [4]2 Rouse_ © (17.06.04 23:06) [33]
ну да, т.к. если в ответ на top 1 0 придет +ОК, то должен прийти и заголовок. (если что-то со связью не случится, но этот вопрос пока не поднимаю)
Rouse_ (2004-06-17 23:06:00) [5]> [31] Verg © (17.06.04 20:25)
Я как понял условие непременно дождаться ответа, поэтому такой код :)
Ivan K (2004-06-17 22:50:00) [6]2 Verg...
А если нечего ждать?%)
Попробую объяснить еще раз.
Цель - получить заголовки писем.
Реализация -
В цикле по i
Send(Sc, 'Top ' + i + ' 0', Length('Top ' + i + ' 0'), 0)
Recv(Sc, A, bytes_in_buffer,0)
далее вычленение из А мыла, сабжа и пр.
Проблема была в том, что я не знал количество возвращаемых данных, а потому ставил наобум 1024 (мол, в килобайт-то поместится), пока не получил письмецо с заголовком поболе... В результате на обработке след. i ничего не нашлось (ибо не было в том аппендиксе никакой нужной инфы). Тогда мне в голову пришла идея! %)) - Надо вызывать Recv, пока он не вернет ошибку... тогда, мол, буфер пустой будет... Кто ж его, заразу, знал, что он дожидаться будет, пока данные откуда-нить возмутся... В результате имеем повешенную наглухо программу.
Вот с таким багажом я открыл сей топик... +)
Verg (2004-06-17 20:25:00) [7]
> [29] Rouse_ © (17.06.04 16:46)
А тогда зачем все это?
Просто Recv и все тут. Она сама подождет с таким же успехом.
Григорьев Антон (2004-06-17 16:50:00) [8]
> Rouse_ © (17.06.04 15:37) [26]
> > Во-первых, ткни меня носом в тот пост, в котором написано,
>
> > что автор вопроса использует SOCK_STREAM, а не SOCK_DGRAM.
>
> Цитирую:
> > А там кроме первого знака "+" есть еще ОК#13#10.
> Вопрос:
> А ты видел чтоб такие сервера работали по UDP?
Есть у меня пробел в образовании - я не знаком с протоколом POP3. Поэтому и не смог распознать, что это за сервер, пока не ткнули :))
Ладно, всем всё понятно, предлагаю прекратить этот оффтопик.
Rouse_ (2004-06-17 16:46:00) [9]Да хоть так делай:
repeat
if ioctlsocket(Cs, FIONREAD, bytes_in_buffer) <> SOCKET_ERROR then
if bytess_in_buffer > 0 then
C := Recv(Cs, A, bytes_in_buffer, 0); // Тут понятно
until bytess_in_buffer > 0;
Ivan K (2004-06-17 16:31:00) [10]
> recv-то c 1024 будет ждать, пока данные в сокете
> появятся, хоть сколько данных, хоть один байт.
>
> if ioctlsocket(Cs, FIONREAD, bytes_in_buffer) <> SOCKET_ERROR
> then
>
> Теперь bytes_in_buffer содержит кол-во байтов, которе на
> данный момент принял сокет со времени последнего recv. Эта-то
> ф-ция ничего не ждет. Она немедленно возвращает запрошенную
> информацию о состоянии буфера приема.
вот... спасибо. теперь понял, в чем тут фишка%)
простите за тормознутость%)
> if ioctlsocket(Cs, FIONREAD, bytes_in_buffer) <> SOCKET_ERROR
> then
> begin
> if bytess_in_buffer > 0 then
> C := Recv(Cs, A, bytes_in_buffer, 0); // Тут понятно
> else
> // А тут что ты намерен делать? Что дальше-то?
> end;
вооот... а вот тут вопрос интересный... теперь, в свете вновь полученных знаний, пока не знаю... По идее, если заголовок пока не прочитался, его надо прочитать, т.е. ждать, пока в Recv что-нить появится...
Rouse_ (2004-06-17 15:37:00) [11]О блин, долго пишу :)
Rouse_ (2004-06-17 15:37:00) [12]> Во-первых, ткни меня носом в тот пост, в котором написано,
> что автор вопроса использует SOCK_STREAM, а не SOCK_DGRAM.
Цитирую:
> А там кроме первого знака "+" есть еще ОК#13#10.
Вопрос:
А ты видел чтоб такие сервера работали по UDP?
Digitman (2004-06-17 15:32:00) [13]
> Григорьев Антон © (17.06.04 15:03) [24]
> Во-первых, ткни
пожалуйста ..
в [15] у автора речь идет о почтовом протоколе POP3, который базируется на поточно-ориентированном транспортном протоколе
Григорьев Антон (2004-06-17 15:03:00) [14]
> Digitman © (17.06.04 13:38) [22]
>
> > Григорьев Антон © (17.06.04 13:27) [21]
>
>
> в [18] жирным выделено важное замечание касаемое ИМЕННО
> stream-oriented sockets.. и речь здесь идет конкретно о
> stream-oriented sockets, а не о каких-то иных
Во-первых, ткни меня носом в тот пост, в котором написано, что автор вопроса использует SOCK_STREAM, а не SOCK_DGRAM. Из его кода это не следует. Во-вторых, если в чьём-то посте я увидел что-то такое, что противоречит тому, что я знаю, я что, имею право на уточняющий вопрос только в том случае, если это что-то выделено жирным шрифтом?
> Rouse_ © (17.06.04 14:03) [23]
Ну тогда всё понятно. В той ссылке, которую ты привел, сверху написано: Microsoft Windows CE .NET 4.2
Rouse_ (2004-06-17 14:03:00) [15]> [19] Григорьев Антон © (17.06.04 12:53)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcewinsk/html/_wcesdk_ioctlsocket.asp
Digitman (2004-06-17 13:38:00) [16]
> Григорьев Антон © (17.06.04 13:27) [21]
в [18] жирным выделено важное замечание касаемое ИМЕННО stream-oriented sockets.. и речь здесь идет конкретно о stream-oriented sockets, а не о каких-то иных
Григорьев Антон (2004-06-17 13:27:00) [17]
> Digitman © (17.06.04 13:16) [20]
Сравни цитаты из поста Rouse_ [18]:
> If s is message-oriented (for example, type SOCK_DGRAM),
> FIONREAD returns the size of the first datagram (message)
> queued on the socket.
и из моего:
> If s is message oriented (for example, type SOCK_DGRAM),
> FIONREAD still returns the amount of pending data in the
> network buffer, however, the amount that can actually be
> read in a single call to the recv function is limited to
> the data size written in the send or sendto function call.
Ты согласен, что в них написано прямо противоположное? Я всего лишь хотел выяснить, откуда расхождение. И про SOCK_DGRAM не я начал, в [18] это уже есть.
Digitman (2004-06-17 13:16:00) [18]
> Григорьев Антон © (17.06.04 12:53) [19]
не в ту степь тебя понесло, даже если хэлп от борланда чем-то на 1-й взгляд не похож на соотв.справку из MSDN
речь в дан.случае идет о stream oriented sockets (SOCK_STREAM), а не о message oriented sockets(SOCK_DGRAM)
..which may not be the same as the total amount of data queued on the socket- вот именно об этом идет речь !
Григорьев Антон (2004-06-17 12:53:00) [19]
> Rouse_ © (17.06.04 12:22) [18]
Откуда цитата? В той версии MSDN'а, которая есть у меня на дисках(Апрель 2001), написано другое:
Use to determine the amount of data pending in the network's input buffer that can be read from socket s. The argp parameter points to an unsigned long value in which ioctlsocket stores the result. FIONREAD returns the amount of data that can be read in a single call to the recv function, which may not be the same as the total amount of data queued on the socket. If s is message oriented (for example, type SOCK_DGRAM), FIONREAD still returns the amount of pending data in the network buffer, however, the amount that can actually be read in a single call to the recv function is limited to the data size written in the send or sendto function call.
Проверил на http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/ioctlsocket_2.asp- написано то же самое. Похоже, у тебя устаревшая информация.
Rouse_ (2004-06-17 12:22:00) [20]FIONREAD
Use FIONREAD to determine the amount of data pending in the network's input buffer that can be read from socket s. The argp parameter points to an unsigned long value in which ioctlsocket stores the result. If s is stream-oriented (for example, type SOCK_STREAM), FIONREAD returns the amount of data that can be read in a single call to the recvfunction; this might not be the same as the total amount of data queued on the socket. If s is message-oriented (for example, type SOCK_DGRAM), FIONREAD returns the size of the first datagram (message) queued on the socket.
+ а какой размер буффера ты выставил через SO_RCVBUF?