Synapse: проверка TCP соединения
Модератор: Модераторы
- Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
Synapse: проверка TCP соединения
Как можно проверять существует ли еще TCP соединение. Библиотека Synapse ararat. Клиентская часть.
1. Клиент устанавливает соединение, делает апгрейд соединение до SSL.
2. Получаем приветствие от TCP сервера.
3. Отправляю команду на логин. Получаю ответ.
Все, можно работать.
Суть в том, что сессия работает в пределах одного логина и одного TCP соединения.
Скорее всего через 5 или 10 минут TCP сервер закрывает сессию и закрывает TCP соединение при бездействии. Чтобы поддерживать соединение можно отправлять команду HELLO на сервер с периодом меньшим, чем время таймаута для сессии.
Но вот вопрос, как проверить на всякий случай перед отправкой: TCP соедение-то еще присутствует или нет? Понятно, можно дождать ответа от сервера с ошибкой, и заново создать соединение и залогинится. Но нет ли какой-либо проверки возможности: могу ли я отправить новую команду серверу в пределах последнего TCP соединения?
P.S. Если кто-то понимает о чем, то я пытаюсь реализовать EPP протокол клиентской части
1. Клиент устанавливает соединение, делает апгрейд соединение до SSL.
2. Получаем приветствие от TCP сервера.
3. Отправляю команду на логин. Получаю ответ.
Все, можно работать.
Суть в том, что сессия работает в пределах одного логина и одного TCP соединения.
Скорее всего через 5 или 10 минут TCP сервер закрывает сессию и закрывает TCP соединение при бездействии. Чтобы поддерживать соединение можно отправлять команду HELLO на сервер с периодом меньшим, чем время таймаута для сессии.
Но вот вопрос, как проверить на всякий случай перед отправкой: TCP соедение-то еще присутствует или нет? Понятно, можно дождать ответа от сервера с ошибкой, и заново создать соединение и залогинится. Но нет ли какой-либо проверки возможности: могу ли я отправить новую команду серверу в пределах последнего TCP соединения?
P.S. Если кто-то понимает о чем, то я пытаюсь реализовать EPP протокол клиентской части
-
MysticCoder
- постоялец
- Сообщения: 154
- Зарегистрирован: 14.09.2013 00:20:28
- Контактная информация:
Re: Synapse: проверка TCP соединения
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.
- Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
Re: Synapse: проверка TCP соединения
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 соединения происходят крайне редко. Что собственно и понятно раз его используют для общения между собой серверы регистраторов и в редких случаях разрешается и клиентам регистраторов.
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: Synapse: проверка TCP соединения
Поддержкой TCP занимается ОС, поэтому все вопросы к ней. Есть два основных способа проверки соединения, это:
- регулярно проверять состояние буферов приёма/отправки неблокирующими функциями через ioctl(socket), в synapse это CanRead/CanWrite и чтение размера буферов.
- назначить Callback и пользоваться блокирующими функциями чтения/записи. Но это довольно сложный и рискованный способ, и не особо кроссплатформенный.
- регулярно проверять состояние буферов приёма/отправки неблокирующими функциями через ioctl(socket), в synapse это CanRead/CanWrite и чтение размера буферов.
- назначить Callback и пользоваться блокирующими функциями чтения/записи. Но это довольно сложный и рискованный способ, и не особо кроссплатформенный.
Re: Synapse: проверка TCP соединения
Ichthyander писал(а):Но вот вопрос, как проверить на всякий случай перед отправкой: TCP соедение-то еще присутствует или нет?
при отправке получишь ошибку это будет означать, что со связью что то случилось..
При чтении данных тоже вывалится ошибка. то же будет означать конец..
Re: Synapse: проверка TCP соединения
TCP не имеет такого понятия. Но можно использовать расширение keep-alive.
http://rsdn.org/article/net/keep_alive.xml
http://rsdn.org/article/net/keep_alive.xml
Re: Synapse: проверка TCP соединения
Код: Выделить всё
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; - Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
Re: Synapse: проверка TCP соединения
Ну по поводу keep-alive и подобных пингов, собственно, примерно об этом я и написал начальном посте топика. Можно периодически отправлять команду HELLO серверу и получать ответы (GREETING) для избежания принудительного разрыва TCP соединения со стороны сервера по причине превышения таймаута. Думал есть родные для TCP сокетов проверки соединения.
---- -----
Чтобы не создавать новой смежной темы по поводу TCP решил опубликовать вновь возникший вопрос здесь же.
Вот у меня есть поток, который после отправки команды освобождается. Сокет (TTCPBlockSocket) создается внутри потока и тоже освобождается соответственно. Традиционно в потоках нужные данные между сессиями и отправками команд к серверу я сохранял передавая данные потока основному. Но вот, что делать в данном случае, если мне нужно сохранить TCP соединение, но объект класса TTCPBlockSocket также соответственно уничтожится.
Варианты:
1. Создавать сокет в основном потоке (при это устанавливать соединение в потоке).
2. Как то можно сохранить TCP соединение между двумя объектами сокета (TTCPBlockSocket)? Чтобы при уничтожении объекта сокета (TTCPBlockSocket) TCP соединение не закрывалось, более того, в последующем при создании нового объекта сокета как-то восстановить данные непрерванного TCP-соединения?
3. Все варианты плохи? И каждый раз авторизоваться для отправки команды (по-моему плохой неоптимальнй вариант)
Добавлено спустя 4 минуты 52 секунды:
Тему с проверкой TCP соединения без отправки или приема сообщения решил "закрыть" для себя. Но все же, можете сопроводить комментариями приведенный Вами код? Я не понял назначения этого кода.
Добавлено спустя 36 минут 14 секунд:
Пока думаю просто создавать и хранить сокет в основном потоке. А уже соединятся и обрабатывать в соответствующем для этого потоке [который иногда останавливается и уничтожается]
---- -----
Чтобы не создавать новой смежной темы по поводу 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 секунд:
Пока думаю просто создавать и хранить сокет в основном потоке. А уже соединятся и обрабатывать в соответствующем для этого потоке [который иногда останавливается и уничтожается]
Re: Synapse: проверка TCP соединения
смысл прост - перед отправкой запроса или данных производится попытка установить подключение. если оно живо - будет LastError = 10056 и код просто пойдет дальше
Добавлено спустя 55 секунд:
а иначе будет произведена попытка нового коннекта
Добавлено спустя 55 секунд:
а иначе будет произведена попытка нового коннекта
- Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
Re: Synapse: проверка TCP соединения
MaratIsk писал(а):смысл прост - перед отправкой запроса или данных производится попытка установить подключение. если оно живо - будет LastError = 10056 и код просто пойдет дальше
Добавлено спустя 55 секунд:
а иначе будет произведена попытка нового коннекта
Хм... Интересно, попробую также
-
MysticCoder
- постоялец
- Сообщения: 154
- Зарегистрирован: 14.09.2013 00:20:28
- Контактная информация:
Re: Synapse: проверка TCP соединения
Ichthyander писал(а):Вот у меня есть поток, который после отправки команды освобождается. Сокет (TTCPBlockSocket) создается внутри потока и тоже освобождается соответственно. Традиционно в потоках нужные данные между сессиями и отправками команд к серверу я сохранял передавая данные потока основному. Но вот, что делать в данном случае, если мне нужно сохранить TCP соединение, но объект класса TTCPBlockSocket также соответственно уничтожится.
Заведи себе какой нибудь менеджер этих сокетов и храни сокеты там. В простейшем случае хотя бы TList.
- Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
Re: Synapse: проверка TCP соединения
MysticCoder писал(а):Ichthyander писал(а):Вот у меня есть поток, который после отправки команды освобождается. Сокет (TTCPBlockSocket) создается внутри потока и тоже освобождается соответственно. Традиционно в потоках нужные данные между сессиями и отправками команд к серверу я сохранял передавая данные потока основному. Но вот, что делать в данном случае, если мне нужно сохранить TCP соединение, но объект класса TTCPBlockSocket также соответственно уничтожится.
Заведи себе какой нибудь менеджер этих сокетов и храни сокеты там. В простейшем случае хотя бы TList.
Более того, мне даже не нужно создавать для этого новый список. Он уже есть по сути. Просто добавил свойство объект.
К моменту этого поста - уже все работает: cохраняю объекты TTCPBlockSocket в основном потоке в массиве объектов для хранения
Re: Synapse: проверка TCP соединения
да никакой магии нет, два хоста пытаются обмениваться сообщением через узлы сами узлы невидимые, пути могут меняться как и фрагментироватся.. там сильно подвязана теория вероятности.Ichthyander писал(а):Думал есть родные для TCP сокетов проверки соединения.
Сделано просто - если от другого хоста пакет не приходит(вроде до 2х дней) TCP соединение будет считаться актуальным.
Keepalive же позволяет прочухать актуальность линка. переодически посылаются ASK пакеты.. если ответа нет после нескольких(все эти параметры корректируются) в течении определенного времени то ось считает, что соединение разорвано. Конечно можно посылать свои HELLO пакеты на уровне приложения..
У меня был опыт работы с GSM связью - там пакеты шли более 2х минут. При таких клиентах нужно это учитывать.
У меня была задача такая: создавался сокет под ним создавался поток который обслуживал данного клиента. Поддерживал протокол. Время жизни сокета равнялось времени жизни потока. По протоколу поток мог завершится и его сокет тоже уничтожался..Ichthyander писал(а):3. Все варианты плохи? И каждый раз авторизоваться для отправки команды (по-моему плохой неоптимальнй вариант)
Понадобилось обмен сообщениями между клиентами. Пришлось делать список регистрации. Создался поток - к нему прикрепился сокет, поток регистрируется в списке.. Если нужно передать данные - делается поиск по этому списку. Когда поток завершается - он выписывается из списка.
Добавлено спустя 13 минут 11 секунд:
Когда встал вопрос про передачу голоса в рамках одного TCP подключения. Стал рассматривать асинхронное передачу данных в рамках этого протокола. Протокол предусматривал гарантированное передачу данных и не гарантированное.
