Synapse. Разрыв соединения.
Модератор: Модераторы
Synapse. Разрыв соединения.
Доброго времени суток! Разбираюсь с synapse. Вопрос следующий: TTCPBlockSocket, подключаемся к серверу методом Connect(IP, Port) Пишу, читаю - всё ОК. Каким образом определить факт отключения сервера(т.е. сервер, грубо говоря, отрубился без всяких уведомлений). Клиент этого не видит и лишь через некоторое время, при попытке записи в порт выдаёт ошибку. Вобщем, необходимо сразу же после отрубания сервера определять факт разрыва связи(аналогично и для сервера). Как быть? Есть какие-то ускользнувшие от моего внимания хитрости?
- *vmr
- постоялец
- Сообщения: 168
- Зарегистрирован: 08.01.2007 00:46:07
- Откуда: Киев
- Контактная информация:
Вобщем клиенту приходит сигнал об об принудительном обрыве коннекта на сервере - смотри ф-ю CanRead. A поскольку у синапса дока бедная, то советую почитать описание ф-и select в MSDN (CanRead -- просто враппер над этой API-шной ф-ей)
Последний раз редактировалось *vmr 09.11.2007 15:06:58, всего редактировалось 1 раз.
Имеется ввиду функция из WinSock 2 что-ли? Тогда не подойдёт - под Linux придется соответствующие костыли использовать. Вобщем, насколько понял, библиотека synapse стандартных средств определения обрыва коннекта не предоставляет и это дело отдается на откуп программиста при разработке под конкретную ось? Можно, конечно, по-дубовому сделать: к примеру, раз в 1 с писать в сокет 0, и ловить ошибку записи, но некошерно как-то:( Эх...
- *vmr
- постоялец
- Сообщения: 168
- Зарегистрирован: 08.01.2007 00:46:07
- Откуда: Киев
- Контактная информация:
1. API сокетов для UNIX и WIN32 совпадают на 95%
2. Простите, я ошибся с названием метода, правильный метод - CanRead
3. Synapse - это довольно тонкий враппер над "голыми" сокетами, потому поведение CanRead там полностью совпадает с поведением API-шной функцией select (смотри сорцы синапса)
4. Я сослался на MSDN, но раз вам надо и под UNIX, то для уверености почитайте и man'ы (уверен, что там будет то же самое)
PS: Я успешно определяю разрыв коннекта только средствами синапса и без всяких "костылей"
PPS: Исправил пост #2
2. Простите, я ошибся с названием метода, правильный метод - CanRead
3. Synapse - это довольно тонкий враппер над "голыми" сокетами, потому поведение CanRead там полностью совпадает с поведением API-шной функцией select (смотри сорцы синапса)
4. Я сослался на MSDN, но раз вам надо и под UNIX, то для уверености почитайте и man'ы (уверен, что там будет то же самое)
PS: Я успешно определяю разрыв коннекта только средствами синапса и без всяких "костылей"
PPS: Исправил пост #2
Поскольку без кода в студии
говорить не конструктивно, то, собственно, вот:
Подключение:
Чтение из сокета в отдельном потоке:
Посмотрел исходники метода CanRead, - действительно, это обёртка над ф-цией Select. В теле метода идёт вызов функции, проверка возвращаемого кода ошибки, заполнение полей fLastError и fLastErrorDesc и генерация исключения(если стоит соответствующий флаг).
Но почему-то при выполнении получается, что CanRead возвращает False тогда, когда всего лишь нет данных для чтения, а св-во LastError всегда равно 0.
, даже при обрыве. Попробовал в обработчике события OnStatus анализировать параметр типа THookSocketReason. При обрыве начинает постоянно выдавать HR_CanRead и лишь при попытке записи появляется HR_Error: 10053, Software caused connection abort
Не понятно.
Подключение:
Код: Выделить всё
procedure TClientIPPort.Open(IP: String; Port: Cardinal);
var
i: Cardinal;
begin
fClientSocket.Bind(fLocalIP, IntToStr(Port+1));
fClientSocket.Connect(IP, IntToStr(Port));
if fClientSocket.LastError <> 0 then
begin
if Assigned(OnError) then
OnError(Self, fClientSocket.LastError, fClientSocket.LastErrorDesc);
Exit;
end;
if Assigned(OnConnect) then
OnConnect(Self);
end;Чтение из сокета в отдельном потоке:
Код: Выделить всё
procedure TClientReadThread.Execute;
var
ReadBuf: array of Byte;
i, ReadCount: Integer;
begin
while not Terminated do
begin
//если можно читать из сокета
if fClientSocket.CanRead(0) then
begin
//кол-во данных, доступных для чтения
ReadCount:= fClientSocket.WaitingData;
if ReadCount > 0 then
begin
SetLength(ReadBuf, ReadCount);
for i:= Low(ReadBuf) to High(ReadBuf) do
ReadBuf[i]:= fClientSocket.RecvByte(500);
.........................
end;
Sleep(1);
end
else
begin
if fClientSocket.LastError <> 0 then
begin
if Assigned(OnError) then
OnError(Self, fClientSocket.LastError, fClientSocket.LastErrorDesc);
if Assigned(OnDisconnect) then
OnDisconnect(Self);
Exit;
end;
end;
end;
end;Посмотрел исходники метода CanRead, - действительно, это обёртка над ф-цией Select. В теле метода идёт вызов функции, проверка возвращаемого кода ошибки, заполнение полей fLastError и fLastErrorDesc и генерация исключения(если стоит соответствующий флаг).
Но почему-то при выполнении получается, что CanRead возвращает False тогда, когда всего лишь нет данных для чтения, а св-во LastError всегда равно 0.
Не понятно.
