2014-01-12 2 views
2

Я начинаю узнавать о том, как реализовать на C++ TCP-сервер/клиент (в Windows и Linux). В настоящий момент я реализую сервер (и тестирование с помощью telnet как клиента). Серверное приложение отправляет и получает данные как шарм. (Я буду реализовывать клиент после понимания всей серверной части). Но мне нужно найти программный (C++ или OS API) способ запроса состояния сокета TCP (ESTABLISHED, FIN_WAIT_2, CLOSE_WAIT и т. Д.) Без использования функции write()/recv() для обработки исключения ошибки.Определить состояние TCP-сокета

Например:

  1. запускает сервер, связать сокет и ждать соединения
  2. а клиент начинает и подключения на сервере
  3. Вот, у меня есть цикл на сервере, что использовать Func " ioctlsocket (socket, FIONREAD, pbytes_available) ", чтобы определить, когда у меня есть данные для чтения.
  4. Если клиент отправляет некоторые данные, тогда «pbytes_available» будет> 1, а сервер будет использовать recv() для получения.
  5. Если клиент ничего не отправляет, сервер может выполнять другие задачи и проверять, есть ли данные в сокете в следующем цикле.
  6. Если я закрываю TELNET (процесс клиента) и запускаю «netstat», я увижу, что сокет сервера находится в состоянии «CLOSE_WAIT», поэтому мне нужно закрыть сокет на стороне сервера.

Это вопрос: Как я могу запросить состояние сокета TCP, чтобы определить, что мне нужно закрыть этот сеанс? (Без использования Send()/ПРИЕМ(), как и "NetStat" делать)

Примечание: Я попробовал "getsockopt (гнездо, SOL_SOCKET, SO_ERROR, & optval, & optlen)", но это возвращение 0, когда состояние ESTABLISHED/CLOSE_WAIT и «optval» также не изменяется.

+1

Вы хотите использовать select() для поиска данных для чтения и исключений. Обратите внимание, что не все ОС сообщают вам, когда другой конец процесса сокета уходит. –

+0

Я хочу получить состояние (например CLOSE_WAIT), например NETSTAT может ... – user2538743

+0

Обычный API-интерфейс BSD не раскрывает эту информацию. Netstat должен использовать определенный способ ОС для получения информации. –

ответ

1

Обычная техника с сокетами в режиме блокировки предназначена для выделения потока для чтения сокета. Когда recv() возвращает 0, это означает, что сверстник закрыл соединение, а порт теперь находится в CLOSE_WAIT состоянии.

В качестве альтернативы вы можете использовать select() и друзей, чтобы рассказать вам, когда сокет читается, включая случай, когда recv() будет возвращать ноль. Использование FIONREAD в качестве механизма опроса действительно довольно бесполезно, поскольку оно не распространяется на этот случай.

Смежные вопросы