Synapse. Разрыв соединения.

Модератор: Модераторы

Synapse. Разрыв соединения.

Сообщение vital » 09.11.2007 01:08:14

Доброго времени суток! Разбираюсь с synapse. Вопрос следующий: TTCPBlockSocket, подключаемся к серверу методом Connect(IP, Port) Пишу, читаю - всё ОК. Каким образом определить факт отключения сервера(т.е. сервер, грубо говоря, отрубился без всяких уведомлений). Клиент этого не видит и лишь через некоторое время, при попытке записи в порт выдаёт ошибку. Вобщем, необходимо сразу же после отрубания сервера определять факт разрыва связи(аналогично и для сервера). Как быть? Есть какие-то ускользнувшие от моего внимания хитрости?
vital
новенький
 
Сообщения: 86
Зарегистрирован: 17.10.2007 14:52:59

Сообщение *vmr » 09.11.2007 01:23:30

Вобщем клиенту приходит сигнал об об принудительном обрыве коннекта на сервере - смотри ф-ю CanRead. A поскольку у синапса дока бедная, то советую почитать описание ф-и select в MSDN (CanRead -- просто враппер над этой API-шной ф-ей)
Последний раз редактировалось *vmr 09.11.2007 16:06:58, всего редактировалось 1 раз.
Аватара пользователя
*vmr
постоялец
 
Сообщения: 168
Зарегистрирован: 08.01.2007 01:46:07
Откуда: Киев

Сообщение vital » 09.11.2007 14:43:27

Имеется ввиду функция из WinSock 2 что-ли? Тогда не подойдёт - под Linux придется соответствующие костыли использовать. Вобщем, насколько понял, библиотека synapse стандартных средств определения обрыва коннекта не предоставляет и это дело отдается на откуп программиста при разработке под конкретную ось? Можно, конечно, по-дубовому сделать: к примеру, раз в 1 с писать в сокет 0, и ловить ошибку записи, но некошерно как-то:( Эх...
vital
новенький
 
Сообщения: 86
Зарегистрирован: 17.10.2007 14:52:59

Сообщение *vmr » 09.11.2007 16:04:20

1. API сокетов для UNIX и WIN32 совпадают на 95%
2. Простите, я ошибся с названием метода, правильный метод - CanRead
3. Synapse - это довольно тонкий враппер над "голыми" сокетами, потому поведение CanRead там полностью совпадает с поведением API-шной функцией select (смотри сорцы синапса)
4. Я сослался на MSDN, но раз вам надо и под UNIX, то для уверености почитайте и man'ы (уверен, что там будет то же самое)


PS: Я успешно определяю разрыв коннекта только средствами синапса и без всяких "костылей" :)
PPS: Исправил пост #2
Аватара пользователя
*vmr
постоялец
 
Сообщения: 168
Зарегистрирован: 08.01.2007 01:46:07
Откуда: Киев

Сообщение vital » 10.11.2007 13:23:28

Поскольку без кода в студии :) говорить не конструктивно, то, собственно, вот:
Подключение:
Код: Выделить всё
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. :shock: , даже при обрыве. Попробовал в обработчике события OnStatus анализировать параметр типа THookSocketReason. При обрыве начинает постоянно выдавать HR_CanRead и лишь при попытке записи появляется HR_Error: 10053, Software caused connection abort
Не понятно.
vital
новенький
 
Сообщения: 86
Зарегистрирован: 17.10.2007 14:52:59

Сообщение vital » 11.11.2007 00:03:25

*vmr писал(а):PS: Я успешно определяю разрыв коннекта только средствами синапса и без всяких "костылей" :)


Не проиллюстрируете кусочком кода? :wink: Если это не коммерческая тайна, конечно. :) Буду весьма признателен.
vital
новенький
 
Сообщения: 86
Зарегистрирован: 17.10.2007 14:52:59

Сообщение Юра » 12.11.2007 11:09:14

Если CanRead возвращает True, но при последующем чтении читается 0 байт, то это означает корректный разрыв соединения.
Юра
постоялец
 
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев


Вернуться в Сети

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru