Подтвердить что ты не робот

Как повторно использовать сокет в .NET?

Я пытаюсь подключиться к сокету, от которого я отключился, но по какой-то причине он не позволит его, хотя я вызвал метод Disconnect с аргументом "reuseSocket", установленным в true.

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(ipAddress, port);
//...receive data
_socket.Disconnect(true); //reuseSocket = true
//...wait
_socket.Connect(ipAddress, port); //throws an InvalidOperationException:

Как только разъем отключен, вы можете снова подключиться снова асинхронно и только к разные конечные точки. BeginConnect должен вызывать на поток, который не будет выходить пока операция не была завершено.

Что я делаю неправильно?

4b9b3361

Ответ 1

Вы можете установить параметры сокета следующим образом

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, True)

Если это не сработает, попробуйте другие опции

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false)
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500)
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, Timeout)

Ответ 2

После чтения документации MSDN для Socket.Disconnect Я заметил что-то, что может вызвать вашу проблему.

Если вам нужно вызвать Disconnect без первого вызова Shutdown, вы можете установить SocketOption с именем DontLinger до false и укажите ненулевой интервал времени ожидания, чтобы обеспечить отправку данных в очередь для исходящей передачи. Затем отключайте блоки до тех пор, пока данные не будут отправлены или пока не истечет указанный тайм-аут. Если вы установите DontLinger в значение false и укажите нулевой интервал времени ожидания, Close отпустит соединение и автоматически отбросит исходящие данные в очереди.

Попробуйте установить опцию DontLinger Socket и укажите тайм-аут 0 или используйте Shutdown, прежде чем вы вызовете отключение.

Ответ 3

Вы пытались добавить эту строку после отключения и до Connect?

client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Ответ 4

От MSDN:

// Release the socket.
client.Shutdown(SocketShutdown.Both);

client.Disconnect(true);
if (client.Connected) 
    Console.WriteLine("We're still connnected");
else 
    Console.WriteLine("We're disconnected");

Если вы используете протокол, ориентированный на соединение, вы можете использовать этот метод для закрытия сокета. Этот метод завершает соединение и устанавливает для свойства Connected значение false. Однако, если reuseSocket истинно, вы можете повторно использовать сокет.

Чтобы гарантировать, что все данные будут отправлены и получены до того, как сокет будет закрыт, перед вызовом метода Disconnect вы должны вызвать Shutdown.

Socket.Shutdown ожидает, что все данные в буфере будут отправлены или получены. Однако, если мы установим только параметры задержки, Socket отключится после определенного интервала времени ожидания.