Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Сетевое программирование > Проблема с сокетами


Автор: ter_nk_ 31.05.19, 12:18
На Stm32

Делаю

int sock = socket(AF_INET, SOCK_STREAM, 0)

Потом result = connect(sock,....

Первое соединение нормально, потом result не 0 а 0xffffffff

errno EISCONN

Хотя должно быть разорвано

Если перед новым соединение делать каждый раз
socket(AF_INET, SOCK_STREAM, 0) то нормально, но на какой-нибудь раз да падает.

Автор: Oleg2004 31.05.19, 15:57
Потом result = connect(sock,....
Цитата ter_nk_ @
Хотя должно быть разорвано

Сколько я понимаю, это у вас некий TCP-клиент, который куда то коннектится
Так вот, закрытие соединения по открытому сокету - единственному на каждый коннект - корректно производится после того, как клиент получил со стороны сервера приглашение закрыть сокет. После того как сервер это предложит, клиентский recv() получает 0. Поэтому всегда следует проверять recv()на 0!!! В Винде после этого клиент должен выполнить closesocket(), а вот в некоторых nix*-совых операционках для корректного завершения соединения надо вызывать две функции
shutdown() а затем close().
Ну и вот вырезка из моего курса лекций
Цитата
Следует также иметь в виду следующее важное обстоятельство. Если соединение по данному сокету не удалось, то сокет (для некоторых типов ошибок) оказывается в неспецифицированном состоянии, и следует обязательно закрыть только-что неудачно использованный сокет. Перед новым вызовом connect(), например в цикле, вновь должен быть произведен вызов socket(). Приложения, соответствующие стандарту POSIX-2001, должны закрыть дескриптор sd с помощью close(), после чего создать новый сокет для продолжения попыток установить соединение. Однако, если попытка соединения не удалась по причинам WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT, то приложение может повторить вызов connect() для этого же сокета. При этом поведение системы зависит от операционной системы. Так, для Windows модуль TCP оставляет для повторного соединения тот же самый локальный порт, который был выбран системой для адреса локального сокета незавершенного соединения. Linux для попытки повторного соединения выбирает следующий свободный номер порта.

Ну вот где то так... :)

Автор: ter_nk_ 31.05.19, 16:17
Цитата Oleg2004 @
Так вот, закрытие соединения по открытому сокету - единственному на каждый коннект - корректно производится после того, как клиент получил со стороны сервера приглашение закрыть сокет. После того как сервер это предложит, клиентский recv() получает 0.


В смысле перед close и shutdown recv вызвать?

Цитата Oleg2004 @
В Винде после этого клиент должен выполнить closesocket(), а вот в некоторых nix*-совых операционках для корректного завершения соединения надо вызывать две функции
shutdown() а затем close().


Там все очень хорошо работает. Я пока сделал так, что каждый раз вызываю так
close() (кроме первого соединения)
socket()
connect()

Добавлено
Спасибо!

Автор: Oleg2004 01.06.19, 20:23
Цитата ter_nk_ @
В смысле перед close и shutdown recv вызвать?

Именно так...с проверкой на 0. Это происходит когда сервер послал сегмент FIN. Клиентская часть TCP это понимает и принимает и сообщает непосредственно программе клиента возвратом в Recv() 0 - нуля...

Добавлено
Цитата ter_nk_ @
Спасибо!

Не за что...если все работает, то и Слава Богу... :)

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)