2011-05-03 26 views
5

descubrí que el código siguiente se reproduce con el 100% de uso de CPU:Por qué toma una lectura de 0 bytes cuando estaba más disponible

byte[] buffer = new byte[0x10000]; 
while (true) { 
    if (socket.Poll (5000000, SelectMode.SelectRead) == false) 
     continue; 
    int available = socket.Available; 
    if (available == 0) 
     return; 
    int read = socket.Receive (buffer); 
    Console.WriteLine ("Read: " + read + " Available: " + available); 
    /* ... */ 
} 

La salida es:

Read: 0 Available: 1 
Read: 0 Available: 1 
Read: 0 Available: 1 
Read: 0 Available: 1 
Read: 0 Available: 1 
... 

me esperaba lo socket.Receive método para leer el byte restante, pero aparentemente no resulta en que mi código se repita al 100%.

Como sugiere jgauffin la documentation lee:

Si el host remoto se apaga la conexión zócalo con el método de apagado y todos los datos disponibles ha ha recibido, el método de recepción se complete inmediatamente y cero de retorno bytes.

Así que la lectura 0 es algo esperado, pero solo después de que se leen todos los datos, qué socket. Los reclamos disponibles no lo son.

La documentación para Socket.Available solo menciona una conexión cerrada que arroja una excepción.

¿Cómo puedo asegurarme de que se lea el último byte?

relacionadas:this es una respuesta de cómo detectar una conexión cerrada que depende de la socket.Available siendo 0 cuando no hay más datos y se cierra la conexión,

+0

Creo que es un error que Disponible devuelve 0 cuando la conexión se ha cerrado. Alguien de MS podría encontrar su pregunta y dar una respuesta adecuada. Lo que puede hacer es intentar enviar algo y ver la cantidad de bytes que devuelve el método Send. Si devuelve 0, la conexión realmente está cerrada. – jgauffin

Respuesta

10

¿Ha leído el documentation ?

0 bytes de lectura significa que el punto final remoto se ha desconectado.

O utilice sockets de bloqueo o utilice los métodos asincrónicos como BeginReceive(). No es necesario Poll en .Net.

+0

Encontré esa parte de la documentación un poco vaga indicando que la desconexión -> lee 0, no necesariamente al revés. ¿Qué tal el Disponible> 0, cómo debería interpretar eso? – hultqvist

+2

Fue hace mucho tiempo que leí el documento. Puedo aceptar que no estaba realmente claro. Debería *** siempre *** tratar a '0' como valor de retorno de' Recibir() 'como desconexión, sin importar lo que digan otros métodos/propiedades. Cita de MSDN: 'Si está en modo sin bloqueo y no hay datos disponibles en el búfer de la pila de protocolos, el método de recepción se completará inmediatamente y arrojará una SocketException'. Recomiendo encarecidamente que deje de usar sockets que no sean de bloqueo en .NET. – jgauffin

+0

Tiene una explicación detallada aquí: http://stackoverflow.com/a/1388691/1529139 – 56ka

Cuestiones relacionadas