Nitin Surya Ответов: 1

Обычно разрешается только одно использование каждого адреса сокета (протокол/сетевой адрес/порт).


Привет
Я разработал tcplistener в vb.net использование tcpServer.dll. ref C# TCP-сервер[^]
здесь все работает нормально, пока есть 2-4 соединения, но если размер соединения увеличивается и я пытаюсь остановить листинг, приложение закрывается. В следующий раз, когда я попытаюсь открыть тот же порт, он покажет мне
Only one usage of each socket address (protocol/network address/port) is normally permitted

Я знаю, что это означает, что порт уже открыт. я закрыл порт на остановке и сформировал событие закрытия
если я это сделаю
netstat -ano
там нет входа в порт, который я пытаюсь открыть
но когда я регистрируюсь в wireshark, я вижу непрерывный прием данных на одном и том же порту.

я даже не могу найти порт в netstat, чтобы убить этот процесс

Что я уже пробовал:

Private Sub btnClose_Click(sender As System.Object, e As System.EventArgs) Handles btnClose.Click
          tcpServer1.Close()
    Close()
End Sub

Private Sub tcpServer1_OnError(server As tcpServer.TcpServer, e As Exception) Handles tcpServer1.OnError
       server.Close()
       server.Open()
   End Sub

1 Ответов

Рейтинг:
1

Jochen Arndt

Проблема заключается в том, что процесс, которому принадлежал сокет (ваше приложение tcplistener), не выполнил надлежащее завершение работы связанных соединений и / или сокетов. В таких случаях порт блокируется на некоторое время - или даже до перезагрузки - прежде чем его можно будет использовать повторно.

Чтобы избежать этого, вы должны выполнить изящное завершение работы. Это также должно позволить клиентам больше не отправлять пакеты (при условии, что они также правильно обрабатывают такие случаи).

Смотреть также Изящное завершение работы, параметры задержки и закрытие сокета | Microsoft Docs[^]. Хотя речь идет о функциях Windows socket API C, она описывает то, что должно быть соблюдено.

Проблема, с которой вы столкнулись, также описана на сайте Использование SO\_REUSEADDR и SO\_EXCLUSIVEADDRUSE | Microsoft Docs[^]:

Цитата:
This issue can become complicated because the underlying transport protocol may not terminate the connection even though the socket has been closed. Even after the socket has been closed by the application, the system must transmit any buffered data, send a graceful disconnect message to the peer, and wait for a corresponding graceful disconnect message from the peer. It is possible that the underlying transport protocol might never release the connection; for example, the peer participating in the original connection might advertise a zero-size window, or some other form of "attack" configuration. In such a case, the client connection remains in an active state despite the request to close it, since unacknowledged data remains in the buffer.

Чтобы избежать этой ситуации, сетевые приложения должны обеспечить плавное завершение работы, вызвав shutdown с установленным флагом SD_SEND, а затем ждать в цикле recv, пока по соединению не будут возвращены нулевые байты. Это гарантирует, что все данные получены одноранговым узлом, а также подтверждает вместе с ним, что он получил все переданные данные, а также позволяет избежать вышеупомянутой проблемы повторного использования порта.

Дальнейшая помощь требует просмотра гораздо большего количества вашего кода.