Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо