Форум: "Сети";
Текущий архив: 2007.03.04;
Скачать: [xml.tar.bz2];
ВнизCloseSocket() в неблокирующем режиме. Вопрос. Найти похожие ветки
← →
DVM © (2006-09-26 11:25) [0]Сокет находится в неблокирующем режиме. Я закрываю сокет функцией CloseSocket(). Вопрос - как мне с гарантией удостовериться, что сокет закрылся. Следом за сокетом мне надо уничтожить поток, в котором сокет используется, но я опасаюсь как бы поток не завершился раньше того как система выполнит всю работу по закрытию сокета. Иначе AV.
← →
Сергей М. © (2006-09-26 11:35) [1]
> Иначе AV
Приведи код, в котором ты получаешь AV после CloseSocket()..
← →
DVM © (2006-09-26 11:47) [2]
> Приведи код, в котором ты получаешь AV после CloseSocket().
> .
Он очень большой, но постараюсь описать подробнее.
Поток делает коннект примерно следующим образом:
function THTTPThread.SocketConnect: integer;
var
Len, Res: integer;
Block: Cardinal;
rfd, wfd: TFDSet;
FTimeout2: TTimeVal;
begin
Result := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if Result <> INVALID_SOCKET then
begin
Block := 1;
ioctlsocket(Result, FIONBIO, Block);
Len := SizeOf(FAddr);
Res := Connect(Result, @FAddr, Len);
FD_ZERO(rfd);
FD_ZERO(wfd);
FTimeout2.tv_sec := 2;
FTimeout2.tv_usec := 0;
while not terminated do
begin
FD_SET(result, rfd);
FD_SET(result, wfd);
case select(0, @rfd, @wfd, nil, @FTimeOut2) of
-1: begin
CloseSocket(Result);
Result := -1;
end;
0: sleep(5);
else
begin
Block := 0;
ioctlsocket(Result, FIONBIO, Block);
break;
end;
end;
end;
end
else
begin
CloseSocket(Result);
Result := -1;
end;
end;
Сначала сокет находится в неблокирующем режиме, потом я его перевожу в блокирующий. Это сделано для того, чтобы ускорить закрытие потока ожидающего connect().
В основном потоке программы я закрываю соединение и вторичный поток так:
if FThread <> nil then
begin
CloseSocket(FThread.Sock);
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
FThread := nil;
end;
Вот я и подумал, а вдруг на момент закрытия сокета он находится в неблокирующем режиме и CloseSocket вернет управление сразу. А далее поток умрет быстрее чем система сокет закроет.
Подмечено, что AV возникает при включенном антивирусе касперского 6 чаще всего. Без него очень очень редко.
← →
DVM © (2006-09-26 11:51) [3]Если изменить так:
if FThread <> nil then
begin
///// CloseSocket(FThread.Sock);
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
FThread := nil;
end;
То вроде работает нормально. (Сижу тестирую). Но поток закрывается теперь медленнее 2-3 секунды. Раньше почти мгновеннно.
← →
DVM © (2006-09-26 11:56) [4]Так же, наверное, замечу, что обращение к FThread.Sock в объекте потока сделано так:
function THTTPThread.GetSock: integer;
begin
FCriticalSection.Enter;
try
Result := FSock;
finally
FCriticalSection.Leave;
end;
end;
← →
Сергей М. © (2006-09-26 12:03) [5]Приведенное тело метода SocketConnect не может вызвать AV - исключение возникает где-то за его пределами. Точнее - на строчке кода, адрес XXXXXXXX которого фигурирует в сообщении об исключении "Access violation at address XXXXXXXX ...".
Ну и явная несуразность здесь присутствует:
if Result <> INVALID_SOCKET then
... //гнездо успешно создано
else
//гнездо не создано
begin
CloseSocket(Result); //закрывать-то при этом нечего - гнездо же не создано !
Result := -1;
end;
end;
← →
DVM © (2006-09-26 12:07) [6]
> Приведенное тело метода SocketConnect не может вызвать AV
> - исключение возникает где-то за его пределами. Точнее -
> на строчке кода, адрес XXXXXXXX которого фигурирует в сообщении
> об исключении "Access violation at address XXXXXXXX ...".
>
Дело в том, что на моей машине повторить ошибку не получается. Она возникает у некоторых пользователей и весьма редко. Строку выявить пока не получается.
> Ну и явная несуразность здесь присутствует:
Да, действительно, не заметил.
← →
Сергей М. © (2006-09-26 12:09) [7]
> поток закрывается теперь медленнее 2-3 секунды
Вместо connect+select используй WSAAsyncSelect/WSAEventSelect + WSAConnect, тогда твой поток сможет оперативно реагировать и на событие коннекта и на сигналы синхронизации, посылаемые потоку в качестве команды "закругляться немедленно"
← →
Сергей М. © (2006-09-26 12:09) [8]
> Строку выявить пока не получается
Почему ?
← →
DVM © (2006-09-26 12:18) [9]
> Почему ?
Чтобы выявить строку, надо дождаться появления ошибки. Ошибка явление крайне редкое и на моем компьютере, как я уже писал, почему то не появляется вовсе. Это главная проблема.
Насчет асинхронных Windows сокетов я подумаю, но, честно говоря, хочется обойтись обычными.
← →
Сергей М. © (2006-09-26 12:28) [10]
> хочется обойтись обычными
Тогда таймаут делай насколько возможно малым.
Это позволит потоку оперативно реагировать на флаг Terminated
> надо дождаться появления ошибки
Не стоит ждать ее сложа руки. К этому моменту ты д.б. вооружен.
Юзер - существо как правило ненадежное, ленивое и недисциплинированное). Маловероятно что юзер ломанется со всех ног докладывать тебе дословный текст исключения тут же после его возникновения (если он вообще почешется по этому поводу), поэтому есть резон обрабатывать глобально все необработанные локально исключения, формировать и посылать протокол таких исключений себе любимому, например, мылом.
← →
DVM © (2006-09-26 15:33) [11]Попутно обнаружил крайне странную вещь! Оказывается KAV 6.0 при включенном анализе HTTP трафика портит данные на выходе. Т.е. они отличаются от того, что на входе.
Если в ответе HTTP сервера приходящем ко мне должно быть изначально #13#10#13#10 - конец заголовка ответа сервера, то после прохождения через касперского получается #13#10#13#10#10#10.
Нет слов!
← →
Сергей М. © (2006-09-26 16:10) [12]
> DVM © (26.09.06 15:33) [11]
При чем здесь антивирь Кашмарского ?)
Ты со своей логикой разберись) ...
← →
DVM © (2006-09-26 17:52) [13]
> При чем здесь антивирь Кашмарского ?)
> Ты со своей логикой разберись) ...
Я же написал "попутно". Со своей логикой разбираюсь. Кроме того, некоторые проблемы с работой моей логики по всей видимости все-таки связаны с данным антивирусом. Проблемы причем не только у меня. Проблемы у многих программ, принимающих потоковые данные типа видео, звука и т.д. В справке для KAV 6 так и написано.
← →
DVM © (2006-09-26 17:53) [14]И то что я написал в [11] - это же явный баг.
← →
Сергей М. © (2006-09-26 21:04) [15]
> В справке для KAV 6 так и написано
"Упалпацтул"(С) славарь падонкафф
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2007.03.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.049 c