как да открия tcp клиентска връзка със сървър в c++

Имам tcp клиент/сървър и искам да открия загуба на връзка от страната на клиента; тъй като клиентът ми има множество интерфейси и в даден момент се свързвах към сървър с един от тях, искам да знам как да открия загуба на връзка от страната на клиента, така че да мога да свържа моя tcp клиент с друг интерфейс към сървъра и дали всички не работят Съхранявам данните си в текстови файлове. Потърсих го в Google и вече видях keep alive, но не е това, което искам.

ако е важно моят проект е в linux и кодът е в c++.


person Lrrr    schedule 22.04.2013    source източник


Отговори (3)


Пробвай да четеш от сокета. Когато гнездото се затвори, четенето ще се провали, което ви дава лесно откриване. Можете да направите това в специална нишка за откриване, така че основната ви нишка да не блокира.

person mah    schedule 22.04.2013
comment
ако интерфейсът е изгубен, това е връзка с интернет, затваря ли това гнездото? (всичките ми интерфейси са 3g) - person Lrrr; 22.04.2013
comment
да Може да отнеме известно време на отдалечената машина да забележи (но вие искате това време да бъде взето, за да предотвратите фалшиво затваряне на сокет поради мрежови проблеми между двете машини). - person mah; 22.04.2013
comment
Защо изобщо бихте отворили връзка и не имате прочетена тема? Нямам предвид в отделна тема. Искам да кажа, какъв е смисълът да имаш клиентска връзка, ако не четеш от сокета? - person Serge Ivanoff; 22.04.2013
comment
@SergeIvanoff не всяко приложение изисква двупосочна комуникация и също така е разумно да има протокол за приложение, който например чете веднъж в началото и след това влиза в цикъл на (голямо забавяне за обработка / и т.н.), пише -- няма нужда да чете междувременно (освен ако искате да откриете отдалечено прекъсване на връзката, за да прекъснете обработката). - person mah; 22.04.2013
comment
Вярно, благодаря. Но четенето може да седи за неопределено време и да не върне неуспешен отговор, ако сокетът не е прекратен, освен ако не кодирате в таймаут. - person Serge Ivanoff; 22.04.2013
comment
Нямате нужда от изчакване при четене непременно. След като вашата локална система разбере, че сокетът вече не е валиден, тя ще деблокира четенето, което ще го накара да се върне (с грешка). Локалната система няма да разбере незабавно, ако дистанционното се срине (или е прекъснато от мрежата и т.н.), така че времето за изчакване все още може да бъде полезно за подобрена реакция, в зависимост от нуждите на приложението. - person mah; 22.04.2013
comment
@mah Четох от сокета, но изглежда, че няма таймаут за това; отнема твърде много време и все още нищо не се връща от функцията за четене! - person Lrrr; 23.04.2013

TCP връзките са проектирани да коригират грешки и да не са критични във времето. Тази корекция на грешка включва изчакване на мрежата.

Четенето и записът няма да се провалят, докато сокетът не бъде действително затворен, което може да не е за много дълго време.

Единственият начин клиентът да реши дали връзката е изтекла е клиентът да открие, че не е получил никакви съобщения за определено време и ръчно да затвори сокета.

За това са съобщенията Keep Alive.

person Serge Ivanoff    schedule 22.04.2013
comment
Моят клиент няма да получи никакви съобщения! поради нашия дизайн само клиентът ще изпраща съобщения до сървъра! ако клиентът ми получи съобщения, ще ми бъде много лесно да открия връзката клиент и сървър! - person Lrrr; 23.04.2013
comment
В такъв случай няма как. Ако има забавяне в мрежата, TCP буферира съобщенията в опит да се възстанови, след като връзката бъде възстановена. Сигурен съм, че има някои причини, поради които ще получите съобщение за пълен буфер, ако пишете твърде много данни, но това зависи от основните размери на мрежовия буфер. Дизайнът на вашия сървър трябва да се промени, за да изпращате съобщения за поддържане на живота (или съобщения за състояние, ако желаете). - person Serge Ivanoff; 24.04.2013
comment
Реших проблема без поддържане на активност и други отговори от сървъра. - person Lrrr; 24.04.2013

Най-добрият начин, който открих, е да проверите буфера, ако буферът е празен, това означава, че вашият TCP клиент е изпратил успешно пакета към TCP сървъра и можете да изпратите следващия пакет; за проверка на буфера можете да използвате SIOCOUTQ; много е лесен за използване и ви показва колко данни имате във вашия буфер.

person Lrrr    schedule 24.04.2013
comment
Готина идея. Как избягвате състояние на състезание, ако проверите този ioctl твърде рано? Също SIOCOUTQ изглежда специфичен за Linux означава, че това не е решение за разработчик на Windows. - person Serge Ivanoff; 26.04.2013
comment
@SergeIvanoff Знам, че не се поддържа в Windows, но както споменах във въпроса, кодирам в Linux и търся решение за моя проблем; Не зададох този въпрос, за да реша други проблеми! ако проверя ioctl твърде скоро, ще изчакам да отговори, ако получа грешка, не затворих сокета си, ако ioctl не отговори, но ще изчакам почти 1 минута и ако през това време данните ми все още остават в буфера, аз ще ми затвори контакта. - person Lrrr; 27.04.2013