Форум: "Сети";
Текущий архив: 2003.04.28;
Скачать: [xml.tar.bz2];
ВнизПроблема: Поток обрабатывающий одно подключение в TServerSocket Найти похожие ветки
← →
ole (2003-03-04 05:06) [0]Бывают моменты, когда поток, обрабатывающий обмен данными с клиентом, продолжает ожидать данные с закрытого соединения.
В результате программа, содержащая TServerSocket, начинает подвисать. Каким образом отключать подвисшие потоки?
Код потока привожу ниже:
procedure ClientExecute;
Var
Stream : TWinSocketStream;
Buffer : Array [0..8096] of byte;
Pack : TPacket Absolute Buffer;
N, T : Integer;
DataSize : Integer;
begin
N:=0;
Stream:=TWinSocketStream.Create(ClientSocket, TimeOut);
try
If Stream.WaitForData(TimeOut) Then
begin
N:=Stream.Read(Buffer,HeadSize);
While N<HeadSize Do
If Stream.WaitForData(TimeOut) Then
N:=N+Stream.Read(Buffer[N],HeadSize-N)
Else Break;
end;
//Заранее известно сколько байт в заголовке пакета.
//Поэтому ожидается именно HeadSize байт.
//Если считать в течении TimeOut не полчается -
//закрывается соединение
//Ниже аналогично считывается блок данных
If N=HeadSize Then
begin
DataSize:=Pack.Header.Len;
//длина данных содержится заголовке пакета
T:=Stream.Read(Buffer[N],DataSize);
While T<DataSize Do
If Stream.WaitForData(TimeOut) Then
T:=T+Stream.Read(Buffer[N+T],DataSize-T)
Else Break;
//пакет получен если T=DataSize;
If T=DataSize Then
begin
If Assigned(FClient.OnBadData)
Then FClient.FOnBadData(ClientSocket.RemoteAddress)
Else//иначе - обрабатываем пришедщий пакет
begin
Move(Buffer, FBuf, N+T);
//отдаем данные для обработки
FHeadSize:=N;
FDataSize:=T;
Synchronize(ParsePacket);
//синхронизируем с визуалом
//здесь выполняется разбор и обработка пакетов
end;
end;
end else
begin
Synchronize(Log);
//процедура записи в лог синхронизируется с визуалом
end;
End;//if
finally
Stream.Free;
ClientSocket.Close;
end;
end;
Что посоветуете?
← →
ole (2003-03-04 05:10) [1]Сразу добавлю - это единовременное подключение.
Клиент передал данные и забыл о них.
Сервер получил и обработал.
← →
Digitman (2003-03-04 08:44) [2]If Stream.WaitForData(TimeOut) Then
begin
............... // чтение из потока
end
else
...//ошибка таймаута, безусловно завершай исполнение метода Execute() !
p.s.
а вот эта строчка
Synchronize(ParsePacket);
сводит на нет все преимущество организации транспорта в доп.код.потоке !
← →
ole (2003-03-04 13:10) [3]Диджитмэн:
Спасибо за ответ. И еще вопрос: разве нет необходимости закрывать открытый сокет?
> сводит на нет все преимущество организации транспорта в
> доп.код.потоке !
Я не могу не использовать синхронизацию. Здесь не так важно, что клиенты будут ожидать... здесь важно в принципе то, что возможно множество одновременных подключений. А в ParsePacket происходит вызов методов-событий родительского компонента (с помощью синхронизации я пытаюсь избежать двойного входения в процедуру)
← →
Digitman (2003-03-04 13:22) [4]
> разве нет необходимости закрывать открытый сокет
в данном конкретном случае - есть ... но - разве об этом речь шла вообще ?
> Я не могу не использовать синхронизацию. Здесь не так важно,
> что клиенты будут ожидать... здесь важно в принципе то,
> что возможно множество одновременных подключений. А в ParsePacket
> происходит вызов методов-событий родительского компонента
> (с помощью синхронизации я пытаюсь избежать двойного входения
> в процедуру)
а какая разница для "родительского компонента", в каком код.потоке происходит возбуждение одного из его событий ? Наверно, таки гораздо важней, в каком потоке оно обрабатываться будет ! А не возбуждаться)
Если уж исполнение запроса требует, по твоей логике, контекста осн.потока, то - разнеси существующий алгоритм из ParsePacket() таким образом, чтобы собственно парсинг пакета происходил в том же (доп.) потоке, а уж исполнение "разобранного и проверенного на целостность/корректность" полученного запроса синхронизировалось с осн.код.потоком
← →
ole (2003-03-06 11:01) [5]
> Digitman
Спасибо.
В том варианте, что я разрабатываю наипростейший метод обработки запросов тот, что я показал. Другой был бы сложнее в организации.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2003.04.28;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.008 c