Как повторно использовать сокет в .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 должен вызывать на поток, который не будет выходить пока операция не была завершено.
Что я делаю неправильно?
Ответы
Ответ 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 отключится после определенного интервала времени ожидания.