Форум: "Сети";
Текущий архив: 2007.04.29;
Скачать: [xml.tar.bz2];
ВнизСтранно ведет себя WaitForData Найти похожие ветки
← →
SpellCaster (2006-11-01 19:28) [0]Столкнулся со странным поведением функции WaitForData в клиентском приложении. Что делаю: запускаю сервер, запускаю клиента. Клиент соединяется и принимает данные, а потом я останавливаю сервер. По идее, WaitForData должна ставить нить на ожидание, а по истечении времени - сообщать, что в канале ничего нет. Однако этого не происходит, и функция возвращает True.
Вот WaitForData, слямзенная из TWinSocketStream
function TClientThread.WaitForData(Timeout: Longint): Boolean;
var FDSet: TFDSet; // структура - список сокетов
TimeVal: TTimeVal; // время, сколько ждать
begin
TimeVal.tv_sec:=Timeout div 1000; // время в с
TimeVal.tv_usec:=(Timeout mod 1000)*1000; // время в мс
FD_ZERO(FDSet); // обнуляем структуру
FD_SET(fClient.Socket.SocketHandle, FDSet); // заносим хэндл
Result:=Select(0,@FDSet,nil,nil,@TimeVal)>0;
end;
и функция чтения
// Чтение Cnt байт из буфера сокета
function TClientThread.ReadBytes(var Buf; Cnt: Integer=1): Integer;
begin
if WaitForData(5000) then // !! вот здесь всё проходит на ура
Result:=fClient.Socket.ReceiveBuf(Buf,Cnt) // !! а здесь возвращает -1
else
begin WriteLog("Таймаут ожидания данных",mkErr); Result:=-1; end; // !! а сюда не попадает!
end;
Функция Select возвращает 1. В чём могут быть грабли?
← →
Сергей М. © (2006-11-02 08:26) [1]
> Функция Select возвращает 1. В чём могут быть грабли?
С чего ты взял, что это "грабли" ?
select() сообщила тебе, что в указанном тобой гнезде произошло некое событие, в твоем случае - разрыв соединения по инициативе партнера.
Читаем справку:
readfds:
· If listening, a connection is pending, accept will succeed
· Data is available for reading (includes OOB data if SO_OOBINLINE is enabled)
· Connection has been closed/reset/terminated
> Result:=fClient.Socket.ReceiveBuf(Buf,Cnt) // !! а здесь
> возвращает -1
Абсолютно нормально. Соединение-от на этот момент уже разорвано !
← →
Сергей М. © (2006-11-02 08:27) [2]
> Функция Select возвращает 1. В чём могут быть грабли?
С чего ты взял, что это "грабли" ?
select() сообщила тебе, что в указанном тобой гнезде произошло некое событие, в твоем случае - разрыв соединения по инициативе партнера.
Читаем справку:
readfds:
· If listening, a connection is pending, accept will succeed
· Data is available for reading (includes OOB data if SO_OOBINLINE is enabled)
· Connection has been closed/reset/terminated
> Result:=fClient.Socket.ReceiveBuf(Buf,Cnt) // !! а здесь
> возвращает -1
Абсолютно нормально. Соединение-от на этот момент уже разорвано !
← →
SpellCaster (2006-11-02 10:48) [3]Так, ясненько. А внутри WaitForData можно как-то определить, что в данном случае произошел именно Connection has been closed/reset/terminated, а не Data is available for reading?
← →
Сергей М. © (2006-11-02 10:53) [4]см. параметр exceptfds ф-ции select()
← →
SpellCaster (2006-11-02 13:12) [5]Посмотрел, видоизменил функцию:
function TClientThread.WaitForData(Timeout: Longint): Boolean;
var FDReadSet,FDExcSet: TFDSet; // структура - список сокетов
TimeVal: TTimeVal; // время, сколько ждать
begin
TimeVal.tv_sec:=Timeout div 1000; // время в с
TimeVal.tv_usec:=(Timeout mod 1000)*1000; // время в мс
FD_ZERO(FDReadSet); // обнуляем структуру
FD_SET(fClient.Socket.SocketHandle, FDReadSet); // заносим хэндл
FD_ZERO(FDExcSet); // обнуляем структуру
FD_SET(fClient.Socket.SocketHandle, FDExcSet); // заносим хэндл
Res:=Select(0,@FDReadSet,nil,@FDExcSet,@TimeVal);
Result:=res>0;
end;
FDExcSet.fd_count равняется нулю. Пробовал заполнять writefds - возвращает 1, т.е. всё ОК.
← →
Сергей М. © (2006-11-02 13:28) [6]
> FDExcSet.fd_count равняется нулю
Э-э-э ... извиняюсь, я соврал тебе.
exceptfds не имеет отношения к событиям дисконнекта.
В целом и общем select() не позволяет получить такую инф-цию.
← →
SpellCaster (2006-11-02 13:44) [7]> [6] Сергей М. © (02.11.06 13:28)
Ничего, бывает. Наверно, легче всего будет просто сделать несколько попыток чтения через некоторый интервал, и если все они оказываются неудачными (-1), дисконнектить сокет. Как думаешь?
← →
Сергей М. © (2006-11-02 14:07) [8]
> SpellCaster (02.11.06 13:44) [7]
> Как думаешь?
Думаю что ты усложняешь понимание проблемы и решение задачи.
У тебя гнездо работает в блок. режиме.
Это означает, что первая же попытка вызова ф-ции чтения из гнезда, вернувшая -1, есть факт произошедшего краха соединения (по тем или иным причинам - неважно каким).
Следовательно, нет никакого резона в дальнейшем продолжать эти попытки, ибо крах соединения налицо. Следует уничтожить гнездо.
Но мне непонятна твоя смесь из готовой логики компонента TClientSocket и WinsockAPI.
Чем эта "смесь" оправдана ? Поясни ...
← →
SpellCaster (2006-11-02 14:42) [9]> У тебя гнездо работает в блок. режиме.
> Это означает, что первая же попытка вызова ф-ции чтения
> из гнезда, вернувшая -1, есть факт произошедшего краха соединения
> (по тем или иным причинам - неважно каким).
> Следовательно, нет никакого резона в дальнейшем продолжать
> эти попытки, ибо крах соединения налицо. Следует уничтожить
> гнездо.
Логично! Пожалуй, так и сделаю.
> Чем эта "смесь" оправдана ? Поясни ...
Видимо, тем, что у TClientSocket нет метода WaitForData. Так бы я не полез в дебри, да я и сейчас не лезу, просто взял процедурку из другого класса. Без таймаута не хочется, перспектива иметь проблемы с зависшими в случае неполадок потоками как-то не внушает оптимизма.
← →
Сергей М. © (2006-11-02 14:52) [10]
> у TClientSocket нет метода WaitForData
Ну так а чем же неблок.режим не устроил ?
Ведь в этом режиме ты совершенно не ограничен в контроле за временем исполнения транспортной операции ..
?
← →
SpellCaster (2006-11-02 15:02) [11]Неблок не устроил размазыванием логики общения между узлами по куче разных процедур... я ведь некоторое время назад доставал тут всех с выбором режима, и в конце концов понял, что с блоком будет легче справиться и не погрязнуть в хитросплетениях событий.
← →
Сергей М. © (2006-11-02 15:05) [12]
> SpellCaster (02.11.06 15:02) [11]
Никаких "хитросплетений событий" в неблок.режиме не существует. ты их выдумал.
Равно как и выдумал проблему с контролемс за состоянием транспорта в блок.режиме.
Короче, ты пытаешься высосать из пальца несуществующую проблему.
← →
SpellCaster (2006-11-02 15:25) [13]Ничего я не пытаюсь, мне и так проблем хватает =). Ну не нравится мне неблок, и всё. А контроля за траспортом тоже никакого нету, есть только выход по таймауту и слежение за результатом чтения. Так что жизнь прекрасна... до следующего бага ). Данная тема исчерпана, благодарю за помощь =)
← →
Сергей М. © (2006-11-02 15:34) [14]
> контроля за траспортом тоже никакого нету
Потому что эт тебе не два проводка, соединяющих батарейку и лампочку на уроках элементарной физики 7-го класса.
Понятие происходящего в TCP-транспорте приходит с внимательным изучением происходящего при этом. И, разумеется, при понимании роли TCP в модели OSI.
← →
SpellCaster (2006-11-02 15:46) [15]> Понятие происходящего в TCP-транспорте приходит с внимательным
> изучением происходящего при этом.
Вот загнул ))).
Но я согласен, до нормального понимания внутренностей протоколов и сокетов мне еще далеко.
← →
medved_68 © (2006-11-02 15:51) [16]
> Видимо, тем, что у TClientSocket нет метода WaitForData.
SpellCaster А почему бы не прикрутить к TClientSocket TWinSocketStream у которого сей метод есть???? :)
← →
Сергей М. © (2006-11-02 16:19) [17]
> SpellCaster (02.11.06 15:46) [15]
>
> > Понятие происходящего в TCP-транспорте приходит с внимательным
> > изучением происходящего при этом.
>
> Вот загнул ))).
В сад.
Ты НЕ хочешь разобраться в происходящем.
← →
SpellCaster (2006-11-02 17:29) [18]> [16] medved_68 © (02.11.06 15:51)
Да не хочется лишний объект создавать, легче функцию слямзить.
> [17] Сергей М. © (02.11.06 16:19)
В чём-то ты прав, мне не очень охота глубоко вникать в технологии. И так забот хватает. НО дело не в этом. Меня поставила в тупик твоя фраза. При чём "при этом"? При TCP-транспорте? Или же "Понятие Х приходит с внимательным изучением Х" ? Ну, с этим-то не поспоришь, и я обеими руками за.
← →
Сергей М. © (2006-11-03 09:38) [19]
> SpellCaster (02.11.06 17:29) [18]
Почитай хотя бы вот это
http://book.itep.ru/4/44/tcp_443.htm
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2007.04.29;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.065 c