Как я могу вызвать ECONNRESET в recv () от клиента? - PullRequest
1 голос
/ 04 мая 2011

Я использую сервер, который аварийно завершает работу после вызова recv (), возвращающего -1, и errno установлен в ECONNRESET.Первоначально я нашел это условие, используя nmap (я не взломщик, просто тестировал, был ли порт открыт в то время.) Однако nmap использует необработанные сокеты, поэтому я не очень рад представить это в качестве тестового примера разработчикам.,Я предпочел бы написать клиентскую программу на C, которая может вызвать ECONNRESET.

До сих пор я пробовал две вещи: connect () к серверу от моего клиента и затем shutdown () сокет сразу после подключения.recv () на сервере все еще возвращает 1 (я вставил код отладки, чтобы я мог видеть возвращаемое значение.) Я также попытался вызвать send () с некоторой строкой, а затем немедленно вызвать shutdown ().Никаких кубиков, строка была передана нормально.

Так как бы я вызвал это условие?Не переносимый - это хорошо, я использую Linux.

Ответы [ 2 ]

5 голосов
/ 04 мая 2011

Проблема в том, что вы звоните shutdown.Вместо этого вызовите close.

Посмотрите на диаграмму состояния TCP.

http://tangentsoft.net/wskfaq/articles/debugging-tcp.html

По сути, shutdown закрывает сокет "вежливо", отправивFIN и ожидание завершения узла (FIN -> ACK / FIN -> ACK -> closed), после чего вы звоните close, и все хорошо.Если вы сначала наберете close без вызова shutdown, это «невежливая» версия, которая отправляет RST - эквивалент зависания в середине телефонного звонка, не дожидаясь, пока другой человек завершит то, что онпоговорка.

Думайте о «выключении» как «попрощайтесь», а «закрывайте» как «повесить трубку».Вы всегда должны вешать трубку, но вам не нужно сначала прощаться.

О nmap: Вполне приемлемо дать разработчикам тестовый пример с nmap.В любом случае, это одна из основных целей nmap.

1 голос
/ 04 мая 2011

Ваши инстинкты были верны для использования shutdown(), однако вы не использовали его правильно для этого.

Предположительно, вы пытаетесь shutdown() с SHUT_WR или SHUT_RDWR.Когда вы закрываете направление записи, как это происходит, ваша сторона соединения уведомляет одноранговый узел с FIN - указывая, что больше никаких данных не будет поступать с вашей стороны.Это приведет к тому, что recv() на другой стороне будет указывать чистый конец файла в соединении, что в данном случае не то, что вам нужно.

Вместо этого вы хотите использовать SHUT_RD дляотключите только направление сокета чтение и держите его открытым для записи.Это не будет немедленно уведомлять однорангового узла - но если одноранговый узел отправляет какие-либо данные после этой точки, ваша сторона ответит RST, чтобы сообщить одноранговому узлу, что некоторые данные были потеряны - они не были замечены вашим клиентским приложением.

(Таким образом, чтобы обеспечить сброс соединения, вам необходимо убедиться, что сервер будет пытаться что-то отправить вам - вам может понадобиться сначала что-то отправить, а затем завершить чтение).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...