![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ServerSocket(stThreadBlocking) - как правильно отсоединится? [D6, D7, Win2k, WinXP]
neodiX © (2003-03-25 19:32:00)Всем привет!
Например есть такой код:
while (not Terminated) and ClientSocket.Connected do
begin
if SockStream.WaitForData(1000*60*60) then //one hour
begin
try
SetLength( s, 10*1024); //RequestBuf
LenReceived := SockStream.Read( s[1], Length(s));
. . .
так вот, когда сокет ждет данных (WaitForData), то, если в этот момент сделать serversocket1.active:=false; то выкидывает ерор.
Может надо поток убить, в котором сервер? Например, в эвенте ОnGetThread пишем:
procedure TScreenFromClient.ScreenServerGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TServerThread.Create( false, ClientSocket);
end;
так мы имеем переменную типа TServerThread (созданный мной). И как теперь обратится к этой переменной чтоб убить поток, она же локальная? А мне надо ИМХО что то вроде такого:
SocketThread.terminate;
Поделитесь кто знает как правильно (чтоб никого еррора не выкидавало) вырубить сервак с подключеными клиентами?
neodiX (2003-03-26 17:53:00) [1]уже говорит :)
спасибо.
Digitman (2003-03-26 17:37:00) [2]If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.
тебе это о чем-то говорит ?
neodiX (2003-03-26 16:43:00) [3]чего то я не догоняю :(
в методе WaitforData() ждется резуьтат функции select,а об возможных результатах этой функиции написано:
select returns the total number of descriptors which are ready and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.
Значит WaitforData() вернет правду только тогда, когда будет заполнена структура fd_set, т.е. когда будут приняты данные. Т.е. мне надо ждать какой то команды?
А может мне сделать таймаут меньше, а по его истечению не ВЫХОДИТЬ из цикла,а просто продолжать код, т.е. в моем случае выполнение перейдет на while not terminated ..... строку.
П.С. так я же тело поточной ф-ции заключил в блок try..except/end, или вы имели ввиду обработать ошибку?
Digitman (2003-03-26 15:51:00) [4]ну а теперь посмотри в текст метода WaitforData() - при каких условиях метод блокирует выполнение код.потока и при каких - возвращает управление (варианты - с возбуждением исключения или с нормальным возвратом результата)
и еще.
тело поточной ф-ции , если в нем могут возникать необработанные тобой искл-е ситуации, ВСЕГДА следует заключать в блок try..except/end, дабы не допустить выход исключения за пределы контекста код.потока
например, SockStream.Read() вполене может вызвать исключение, и в этом случае "граблями по лбу" тебе схлопотать 100%-но обеспечено)
neodiX (2003-03-26 15:31:00) [5]2 Digitman:
>достаточно закрыть гнездо из другого потока, чтобы "стронуть с места" WaitForData
это как? с какого другого потока?
Полный код не могу, но всю суть пожалуйста:
Procedure TServerThread.ClientExecute;
var
ReplyBuf : string;
LenReceived : integer;
t:integer;
h,s:string;
begin
SockStream := TWinSocketStream.Create( ClientSocket, 60000);
Bmp:=Tbitmap.Create;
while (not Terminated) and ClientSocket.Connected do
begin
if SockStream.WaitForData(1000*60*60) then //one hour
begin
try
SetLength( s, 10*1024); //RequestBuf
LenReceived := SockStream.Read( s[1], Length(s));
if LenReceived > 0 then
begin
SetLength( s, LenReceived );
//сдесь происходит обработка полученных данных
end
else BREAK; // client has send zero data
except
BREAK; // stream read error, unexpected disconnect, ...
end;
end
else BREAK; // client did not send data within timeout limit
end;
SockStream.Free;
SockStream := nil;
ClientSocket.Close;
end;
Polevi (2003-03-26 14:53:00) [6]2Digitman © (26.03.03 10:40)
тогда и SocketThread.terminate не нужен -
and ClientSocket.Connected
отработает :-)
Digitman (2003-03-26 10:40:00) [7]достаточно закрыть гнездо из другого потока, чтобы "стронуть с места" WaitForData
Polevi (2003-03-26 09:57:00) [8]>она же локальная
сохраняй ссылки в списке
>SocketThread.terminate;
это тебе не поможет при твоем подходе, WaitForData усыпит поток и проверка
while (not Terminated) and ClientSocket.Connected do
не получит управления, если клиент не будет посылать данные
Digitman (2003-03-26 08:39:00) [9]приведи свой полный код метода ClientExecute