2010-04-23 42 views
12

Estoy intentando volver a conectarme a un socket del que me he desconectado, pero no lo permitirá por algún motivo, aunque llamé al método Disconnect con el argumento "reuseSocket" establecido en verdadero.¿Cómo reutilizar el socket en .NET?

_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: 

Una vez que el conector se haya desconectado, sólo se puede volver a conectar de nuevo de forma asíncrona, y sólo a un diferente de punto final. Se debe llamar a BeginConnect en un hilo que no saldrá de hasta que se complete la operación .

¿Qué estoy haciendo mal?

+0

Probablemente, no debe volver a utilizar el zócalo y simplemente cree uno nuevo. Nunca llame a 'Disconnect', envuélvalo en' using' en su lugar. Además, llame a 'Shutdown'. – usr

Respuesta

3

Después de leer la documentación de MSDN para Socket.Disconnect noté algo que podría estar causando su problema.

Si necesita llamar Desconectar sin primero apagado de llamada, puede ajustar la SocketOption llamado DontLinger-false y especificar un intervalo de tiempo de espera distinto de cero para asegurar que los datos en cola para la transmisión de salida se envía. Desconecte los bloques hasta que se envíen los datos o hasta que expire el tiempo de espera especificado. Si configura DontLinger en falso y especifica un intervalo de tiempo de espera cero, Cerrar libera la conexión y descarta automáticamente los datos salientes en cola.

establecer la opción DontLinger zócalo Try y especifique un tiempo de espera de 0 o utilizar Shutdown antes de llamar a la desconexión.

+1

Lo curioso es que no existe tal propiedad o método llamado 'DontLingerSocket'. Lo más parecido a esto es una propiedad llamada 'LingerState'.Sin embargo, puede instanciar un 'LingerOption' y configurarlo, pero no hay ninguna diferencia si intenta volver a conectarse después de llamar a 'Desconectar'. Y no puede reutilizar un socket si llama 'Cerrar' porque eso eliminará el socket. –

+0

Se perdió un espacio allí, deberían haber sido dos palabras "DontLinger" y "Socket". Una mejor manera de expresar esa oración es * "... llamando a Shutdown, puede configurar [SocketOption] (http://msdn.microsoft.com/en-us/library/e160993d.aspx) con el nombre [DontLinger] (http : //msdn.microsoft.com/en-us/library/system.net.sockets.socketoptionname.aspx) a falso y especifique un valor distinto de cero ... "* –

+0

@ScottChamberlain debidamente anotado. – James

0

De 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"); 

Si está utilizando un protocolo orientado a la conexión, puede utilizar este método para cerrar el zócalo. Este método finaliza la conexión y establece la propiedad Connected en false. Sin embargo, si reuseSocket es verdadero, puede reutilizar el socket.

Para asegurarse de que todos los datos se envían y reciben antes de que se cierre el socket, debe llamar a Shutdown antes de llamar al método Disconnect.

Socket.Shutdown método espera hasta que se hayan enviado o recibido todos los datos en el búfer. Sin embargo, si solo configuramos las opciones de demora, el Socket se apagará después de cierto intervalo de tiempo de espera.

+0

Probé eso, no funciona. –

+1

@Hermann: Creo que tendrás que esperar unos segundos (tiempo de espera) para que el socket sea "reutilizable", puedes intentar poner tu socket en un hilo - para reintentos ... solo pensar; lea más sobre el 'graceful shudown', http://msdn.microsoft.com/en-us/library/ms738547(VS.85).aspx –

+0

NOTA:' client.Connected' se define como el estado de conexión a partir de el 'Enviar' o' Recibir' más reciente, no el estado actual. Y como acaba de llamar a 'Desconectar', los mensajes deberían ser' 'Estamos conectados '' y' 'No estábamos conectados ''. –

4

Puede configurar las opciones de los conectores de este tipo

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

Si esto no funciona, intente algunas otras opciones

_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) 
1

¿Usted intentó añadir esta línea después de la desconexión y antes Connect?

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