Как сетевой инженер, я очень хорошо знаком с операциями TCP. Будучи программистом, я занимался программированием сокетов, но никогда не писал никаких производственных услуг.TCP-открытые соединения TCP, Winsock, Listen/Accept Behavior
У нас есть система поставщиков, которая интегрируется с камерами PTZ (панорамирование/наклон/масштабирование). Камеры наблюдают за пациентами. Данные камеры передаются на сервер поставщика. Сервер поставщика передает данные камеры клиентам. (Это делает больше, но это простой случай.) Если клиент хочет настроить камеру, клиент отправляет пользовательскую команду в настраиваемую службу на сервере поставщика. Сервер интерпретирует команду и отправляет ее на камеру. Камера движется.
У нас возникла проблема, когда служба PTZ на сервере сбой. Во время тестирования с захватами сети мы обнаружили, что служба разбилась примерно в то время, когда nmap
выполнил полуоткрытое (эмбриональное) соединение - nmap отправил SYN, сервер ответил с SYN/ACK, nmap не отправил окончательный ACK. Сервер отправил дубликаты SYN/ACK, пытаясь завершить сеанс и не удалось.
Что я хочу понять: служба использует listen
для просмотра TCP-соединений, а затем использует accept
, чтобы принять соединение. В какой момент listen
рассказать об услуге есть новое соединение, готовое быть accept
ed? Должно ли быть установлено соединение TCP до того, как listen
передает его службе, чтобы она была accept
? Или сервер просто должен вернуть SYN/ACK до того, как listen
сообщит службе?
Если рукопожатие должно быть полным - SYN, SYN/ACK, ACK - перед сообщением listen
, то я могу пойти по неправильному пути. Если сокет просто нуждается в доступе к SYN/ACK, может возникнуть проблема с обработкой службы неполного сеанса. Другое тестирование, когда мы завершаем сеанс TCP и отправляем фиктивные данные, пытающиеся вызвать службу, - не привело к сбою службы. Но повторный тест nmap
довольно надежно сбивает его, поэтому я склоняюсь к проблеме полуоткрытого соединения.
Думаю, у меня это есть. Таким образом, представляя черный ящик, который является системой поставщика, поставщик скорее всего сидит на 'select()' вместо 'listen()'. Итак, точка 2, когда соединение «готово и ждет». , , это означает, что рукопожатие завершено? Клиент отправил TCP ACK? Или он все еще может «быть готовым и ждать» в ожидании конечного клиента ACK? –
Как я сказал в своем ответе: «* Только ** полностью установленные ** соединения доступны для' accept() ', ... *". Так что да, квитирование связи должно быть завершено до того, как код когда-либо увидит соединение. –
Спасибо Реми. Очень ценится. Это означает, что полуоткрытое соединение не повреждает службу, поэтому должно быть что-то отправлено службе. Но мы просто не можем определить, что это такое. Теперь, когда я понимаю, как 'listen()', 'select()' и 'accept()' работают вместе и с стек протоколов, я буду продолжать искать. Еще раз спасибо! –