Как повторно использовать сокет в .NET? - PullRequest
14 голосов
/ 23 апреля 2010

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

Что я делаю не так?

Ответы [ 4 ]

4 голосов
/ 11 июня 2012

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

_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)
4 голосов
/ 23 апреля 2010

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

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

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

1 голос
/ 11 июня 2015

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

client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
0 голосов
/ 23 апреля 2010

С 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 имеет значение true, вы можете повторно использовать сокет.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...