2010-12-03 6 views
7

Estoy utilizando la clase toma de .Net y estoy usando el siguiente código:¿Por qué .Net Socket.Disconnect toma dos minutos?

socket.Shutdown(SocketShutdown.Both); 
socket.Disconnect(true); 

esto, entonces los bloques de exactamente dos minutos. He especificado verdadero porque voy a reutilizar el socket inmediatamente y restablecer la conexión. Si tengo la llamada de apagado allí o no, bloquea durante dos minutos. Lo único que puedo hacer es pasar falso para desconectarme. Pero quiero reutilizar el socket.

¿Alguna idea?

ACTUALIZACIÓN:

He leído los códigos. He configurado la opción DontLinger. No ayuda.

ACTUALIZACIÓN 2:

He añadido una traza de red según la petición:

Traza 1: Uso de la opción DontLinger

System.Net.Sockets Verbose: 0 : [4668] Socket#5009246::Socket(InterNetwork#2) 
System.Net.Sockets Verbose: 0 : [4668] Exiting Socket#5009246::Socket() 
System.Net.Sockets Verbose: 0 : [4668] Socket#5009246::Connect(eee:nnnn#-2063562120) 
System.Net.Sockets Information: 0 : [4668] Socket#5009246 - Created connection from aaa.bbb.ccc.ddd.eee:nnnnn to www.xxx.yyy.zzz.:mmmm. 
System.Net.Sockets Verbose: 0 : [4668] Exiting Socket#5009246::Connect() 
System.Net.Sockets Verbose: 0 : [4668] Socket#5009246::Disconnect() 
System.Net.Sockets Verbose: 0 : [4668] Exiting Socket#5009246::Disconnect() 

Traza 2: Usando el apagado (SocketShutdown. Ambos);

System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Socket(InterNetwork#2) 
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Socket() 
System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Connect(ddd:eeeee#-2063562120) 
System.Net.Sockets Information: 0 : [0300] Socket#5009246 - Created connection from aaa.bbb.ccc.ddd:eeee to www.xxx.yyyy.zzzz:nnnnn. 
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Connect() 
System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Shutdown(Both#2) 
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Shutdown() 
System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Disconnect() 
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Disconnect() 
+0

¿Podemos ver el código que lo rodea? podría ser que haya algo más que cause la demora, como un ciclo o una llamada de bloqueo. –

Respuesta

-2

Resulta que hay una entrada de registro que controla el tiempo de desconexión. Tiene algo que ver con la API de WinSock2.

+2

¿Puedes explicar esto más? Estoy teniendo el mismo problema aquí ... – Leonardo

+0

También teniendo el mismo problema, ¿cuál era la resolución? –

0

Eso puede ser para la opción Linger. Consulte aquí para obtener más información: Graceful Shutdown, Linger Options, and Socket Closure

en .NET, puede cambiarlo con el método Socket.SetSocketOption.

EDITAR: si no es la opción Linger, usted debe tratar de permitir que los rastros de socket completos, aquí es una muestra .config:

<configuration> 
    <system.diagnostics> 
    <trace autoflush="true" /> 
    <sources> 
     <source name="System.Net.Sockets"> 
     <listeners> 
      <add name="SocketsTrace"/> 
     </listeners> 
     </source> 
    </sources> 

    <sharedListeners> 
     <add name="SocketsTrace" type="System.Diagnostics.TextWriterTraceListener" initializeData="SocketsTrace.log" /> 
    </sharedListeners> 

    <switches> 
     <add name="System.Net.Sockets" value="Verbose" /> 
    </switches> 
</configuration> 

EDITAR: o puede golpear lo que se llama el TIME_WAIT , descrito aquí: Please explain the TIME_WAIT state que es 120ms. En general, es mejor utilizar Close() con SocketOptionName.ReuseAddress en lugar de usar Disconnect (true). Ver comentarios here también (en la sección de comentarios).

+0

Ya he intentado configurar la opción DontLinger. No funciona. De todas formas usé Socket.ShutDown así que no debería ser necesario. – uriDium

+0

idea: intente habilitar el rastreo (He actualizado mi respuesta) –

+0

He intentado con no demorarme y desactivar y obtener el mismo rastro. He actualizado mi pregunta con el rastro. – uriDium

1

Esto podría ser lo que estás buscando.

Si necesita llamar Desconectar sin primero apagado de llamada, puede establecer la opción DontLinger zócalo en 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.

A partir del docs.

+0

Ya he leído esto. No funciona. A pesar de que la parte dice SIN. Bueno, llamé a shutdown para que todo eso no sea válido. – uriDium

+0

Por lo que sé, si se utiliza el apagado, esto provoca que "todos los datos se envíen y reciban antes de que se cierre el socket" [Documentos]. Esto da como resultado el retraso de 2 minutos, porque está terminando el envío y la recepción de datos antes del cierre. El retraso podría ser más largo o más corto según los datos que se envían/​​reciben. –

+0

Por lo tanto, elige retrasar durante 2 minutos para garantizar que los datos se envían/​​reciben. Eso suena horrible. – uriDium

3

Tiempo de espera en caso de Apagar seguido de Desconectar o Comenzar a desconectar se producirá en el caso si el Enchufe del otro lado no está recibiendo.

aquí cómo funciona: apagado (SocketShutdown.Send) (o ambos) producen enviando de cero bytes a otro lado. Y luego, si llama a Desconectar, se bloqueará hasta que el otro lado acepte este paquete de cero bytes. Es por esto que el socket siempre recibe byte cero durante en Aceptar durante la elegante desconexión de Socket. La opción de persistencia y otras configuraciones no tienen efecto en este retraso de 2 minutos. Puede verificar el estado de la conexión con TCPView. Así que la forma correcta es asegurarse de que el otro lado esté en modo de recepción O físicamente desconectado O que el socket esté realmente destruido, por ejemplo, la aplicación se cierra (en este caso, obtendrá una excepción inmediata sin demora de 2 minutos).

http://vadmyst.blogspot.ru/2008/04/proper-way-to-close-tcp-socket.html

Cuestiones relacionadas