Synapse: проверка TCP соединения

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

Synapse: проверка TCP соединения

Сообщение Ichthyander » 15.07.2018 12:37:21

Как можно проверять существует ли еще TCP соединение. Библиотека Synapse ararat. Клиентская часть.
1. Клиент устанавливает соединение, делает апгрейд соединение до SSL.
2. Получаем приветствие от TCP сервера.
3. Отправляю команду на логин. Получаю ответ.
Все, можно работать.
Суть в том, что сессия работает в пределах одного логина и одного TCP соединения.
Скорее всего через 5 или 10 минут TCP сервер закрывает сессию и закрывает TCP соединение при бездействии. Чтобы поддерживать соединение можно отправлять команду HELLO на сервер с периодом меньшим, чем время таймаута для сессии.
Но вот вопрос, как проверить на всякий случай перед отправкой: TCP соедение-то еще присутствует или нет? Понятно, можно дождать ответа от сервера с ошибкой, и заново создать соединение и залогинится. Но нет ли какой-либо проверки возможности: могу ли я отправить новую команду серверу в пределах последнего TCP соединения?
P.S. Если кто-то понимает о чем, то я пытаюсь реализовать EPP протокол клиентской части
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 442
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Synapse: проверка TCP соединения

Сообщение MysticCoder » 15.07.2018 13:28:15

function RecvBuffer(Buffer: TMemory; Length: Integer): Integer; virtual;

Note: This is low-level receive function. You must be sure if data is waiting for read before call this function for avoid deadlock!

Waits until allocated buffer is filled by received data. Returns number of data received, which equals to LENGTH value under normal operation. If it is not equal the communication channel is possibly broken.

On stream oriented sockets if is received 0 bytes, it mean 'socket is closed!"

On datagram socket is readed first waiting datagram.
MysticCoder
постоялец
 
Сообщения: 145
Зарегистрирован: 14.09.2013 00:20:28

Re: Synapse: проверка TCP соединения

Сообщение Ichthyander » 15.07.2018 13:52:55

MysticCoder писал(а):
function RecvBuffer(Buffer: TMemory; Length: Integer): Integer; virtual;

Note: This is low-level receive function. You must be sure if data is waiting for read before call this function for avoid deadlock!

Waits until allocated buffer is filled by received data. Returns number of data received, which equals to LENGTH value under normal operation. If it is not equal the communication channel is possibly broken.

On stream oriented sockets if is received 0 bytes, it mean 'socket is closed!"

On datagram socket is readed first waiting datagram.

Ну в моем конкретном случае, я не ожидаю входящего пакета. Мне нужно просто отправить пакет данных, а уже потом получать пакет данных. По ошибке LastError узнаю, конечно, что соединение разорвано. Но, как и в приведенном Вами случае, узнаем об этом "постфактум" в виде неудавшейся отправке или приема данных. Я думал, может есть какой-то флаг или функция проверки, типа CanRead или CanWrite.
Видимо протокол EPP создан для случаев когда между сервером и клиентом очень стабильное и быстрое соединение, когда разрывы TCP соединения происходят крайне редко. Что собственно и понятно раз его используют для общения между собой серверы регистраторов и в редких случаях разрешается и клиентам регистраторов.
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 442
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Synapse: проверка TCP соединения

Сообщение serbod » 15.07.2018 14:06:20

Поддержкой TCP занимается ОС, поэтому все вопросы к ней. Есть два основных способа проверки соединения, это:
- регулярно проверять состояние буферов приёма/отправки неблокирующими функциями через ioctl(socket), в synapse это CanRead/CanWrite и чтение размера буферов.
- назначить Callback и пользоваться блокирующими функциями чтения/записи. Но это довольно сложный и рискованный способ, и не особо кроссплатформенный.
Аватара пользователя
serbod
постоялец
 
Сообщения: 351
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Synapse: проверка TCP соединения

Сообщение olegy123 » 15.07.2018 14:31:19

Ichthyander писал(а):Но вот вопрос, как проверить на всякий случай перед отправкой: TCP соедение-то еще присутствует или нет?

при отправке получишь ошибку это будет означать, что со связью что то случилось..
При чтении данных тоже вывалится ошибка. то же будет означать конец..
olegy123
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 25.02.2016 12:10:20

Re: Synapse: проверка TCP соединения

Сообщение Pavia » 15.07.2018 16:20:20

TCP не имеет такого понятия. Но можно использовать расширение keep-alive.
http://rsdn.org/article/net/keep_alive.xml
Аватара пользователя
Pavia
постоялец
 
Сообщения: 214
Зарегистрирован: 07.01.2011 12:46:51

Re: Synapse: проверка TCP соединения

Сообщение MaratIsk » 17.07.2018 17:58:50

Код: Выделить всё
    FSynClient.Connect(FHost, FPort);
    if (FSynClient.LastError <> 0) and (FSynClient.LastError <> 10056) then begin
      try
        FSynClient.CloseSocket;
        FSynClient.Connect(FHost, FPort);
        if (FSynClient.LastError <> 0) then
         raise Exception.Create(IntToStr(FSynClient.LastError) + ' ' + FSynClient.LastErrorDesc);
      except
        raise;
      end;
    end;
MaratIsk
новенький
 
Сообщения: 82
Зарегистрирован: 20.08.2009 18:15:20

Re: Synapse: проверка TCP соединения

Сообщение Ichthyander » 17.07.2018 18:03:13

Ну по поводу keep-alive и подобных пингов, собственно, примерно об этом я и написал начальном посте топика. Можно периодически отправлять команду HELLO серверу и получать ответы (GREETING) для избежания принудительного разрыва TCP соединения со стороны сервера по причине превышения таймаута. Думал есть родные для TCP сокетов проверки соединения.
---- -----
Чтобы не создавать новой смежной темы по поводу TCP решил опубликовать вновь возникший вопрос здесь же.
Вот у меня есть поток, который после отправки команды освобождается. Сокет (TTCPBlockSocket) создается внутри потока и тоже освобождается соответственно. Традиционно в потоках нужные данные между сессиями и отправками команд к серверу я сохранял передавая данные потока основному. Но вот, что делать в данном случае, если мне нужно сохранить TCP соединение, но объект класса TTCPBlockSocket также соответственно уничтожится.
Варианты:
1. Создавать сокет в основном потоке (при это устанавливать соединение в потоке).
2. Как то можно сохранить TCP соединение между двумя объектами сокета (TTCPBlockSocket)? Чтобы при уничтожении объекта сокета (TTCPBlockSocket) TCP соединение не закрывалось, более того, в последующем при создании нового объекта сокета как-то восстановить данные непрерванного TCP-соединения?
3. Все варианты плохи? И каждый раз авторизоваться для отправки команды (по-моему плохой неоптимальнй вариант)

Добавлено спустя 4 минуты 52 секунды:
MaratIsk писал(а):
Код: Выделить всё
    FSynClient.Connect(FHost, FPort);
    if (FSynClient.LastError <> 0) and (FSynClient.LastError <> 10056) then begin
      try
        FSynClient.CloseSocket;
        FSynClient.Connect(FHost, FPort);
        if (FSynClient.LastError <> 0) then
         raise Exception.Create(IntToStr(FSynClient.LastError) + ' ' + FSynClient.LastErrorDesc);
      except
        raise;
      end;
    end;

Тему с проверкой TCP соединения без отправки или приема сообщения решил "закрыть" для себя. Но все же, можете сопроводить комментариями приведенный Вами код? Я не понял назначения этого кода.

Добавлено спустя 36 минут 14 секунд:
Пока думаю просто создавать и хранить сокет в основном потоке. А уже соединятся и обрабатывать в соответствующем для этого потоке [который иногда останавливается и уничтожается]
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 442
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Synapse: проверка TCP соединения

Сообщение MaratIsk » 17.07.2018 19:01:35

смысл прост - перед отправкой запроса или данных производится попытка установить подключение. если оно живо - будет LastError = 10056 и код просто пойдет дальше

Добавлено спустя 55 секунд:
а иначе будет произведена попытка нового коннекта
MaratIsk
новенький
 
Сообщения: 82
Зарегистрирован: 20.08.2009 18:15:20

Re: Synapse: проверка TCP соединения

Сообщение Ichthyander » 17.07.2018 19:13:05

MaratIsk писал(а):смысл прост - перед отправкой запроса или данных производится попытка установить подключение. если оно живо - будет LastError = 10056 и код просто пойдет дальше

Добавлено спустя 55 секунд:
а иначе будет произведена попытка нового коннекта

Хм... Интересно, попробую также
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 442
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Synapse: проверка TCP соединения

Сообщение MysticCoder » 17.07.2018 23:07:16

Ichthyander писал(а):Вот у меня есть поток, который после отправки команды освобождается. Сокет (TTCPBlockSocket) создается внутри потока и тоже освобождается соответственно. Традиционно в потоках нужные данные между сессиями и отправками команд к серверу я сохранял передавая данные потока основному. Но вот, что делать в данном случае, если мне нужно сохранить TCP соединение, но объект класса TTCPBlockSocket также соответственно уничтожится.

Заведи себе какой нибудь менеджер этих сокетов и храни сокеты там. В простейшем случае хотя бы TList.
MysticCoder
постоялец
 
Сообщения: 145
Зарегистрирован: 14.09.2013 00:20:28

Re: Synapse: проверка TCP соединения

Сообщение Ichthyander » 17.07.2018 23:17:52

MysticCoder писал(а):
Ichthyander писал(а):Вот у меня есть поток, который после отправки команды освобождается. Сокет (TTCPBlockSocket) создается внутри потока и тоже освобождается соответственно. Традиционно в потоках нужные данные между сессиями и отправками команд к серверу я сохранял передавая данные потока основному. Но вот, что делать в данном случае, если мне нужно сохранить TCP соединение, но объект класса TTCPBlockSocket также соответственно уничтожится.

Заведи себе какой нибудь менеджер этих сокетов и храни сокеты там. В простейшем случае хотя бы TList.

Более того, мне даже не нужно создавать для этого новый список. Он уже есть по сути. Просто добавил свойство объект.
К моменту этого поста - уже все работает: cохраняю объекты TTCPBlockSocket в основном потоке в массиве объектов для хранения
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 442
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Synapse: проверка TCP соединения

Сообщение olegy123 » 18.07.2018 00:29:06

Ichthyander писал(а):Думал есть родные для TCP сокетов проверки соединения.
да никакой магии нет, два хоста пытаются обмениваться сообщением через узлы сами узлы невидимые, пути могут меняться как и фрагментироватся.. там сильно подвязана теория вероятности.
Сделано просто - если от другого хоста пакет не приходит(вроде до 2х дней) TCP соединение будет считаться актуальным.
Keepalive же позволяет прочухать актуальность линка. переодически посылаются ASK пакеты.. если ответа нет после нескольких(все эти параметры корректируются) в течении определенного времени то ось считает, что соединение разорвано. Конечно можно посылать свои HELLO пакеты на уровне приложения..
У меня был опыт работы с GSM связью - там пакеты шли более 2х минут. При таких клиентах нужно это учитывать.

Ichthyander писал(а):3. Все варианты плохи? И каждый раз авторизоваться для отправки команды (по-моему плохой неоптимальнй вариант)
У меня была задача такая: создавался сокет под ним создавался поток который обслуживал данного клиента. Поддерживал протокол. Время жизни сокета равнялось времени жизни потока. По протоколу поток мог завершится и его сокет тоже уничтожался..
Понадобилось обмен сообщениями между клиентами. Пришлось делать список регистрации. Создался поток - к нему прикрепился сокет, поток регистрируется в списке.. Если нужно передать данные - делается поиск по этому списку. Когда поток завершается - он выписывается из списка.

Добавлено спустя 13 минут 11 секунд:
Когда встал вопрос про передачу голоса в рамках одного TCP подключения. Стал рассматривать асинхронное передачу данных в рамках этого протокола. Протокол предусматривал гарантированное передачу данных и не гарантированное.
olegy123
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 25.02.2016 12:10:20


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

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

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

Рейтинг@Mail.ru