2012-05-31 6 views
6

Estoy escribiendo una capa de mensaje para mi sistema distribuido. Estoy usando IOCP, es decir, los métodos Socket.XXXAsync.El búfer SocketAsyncEventArgs está lleno de ceros

Aquí hay algo muy parecido a lo que estoy haciendo (de hecho, mi función de recepción se basa en él): http://vadmyst.blogspot.com/2008/05/sample-code-for-tcp-server-using.html

Lo que he encontrado ahora es que al inicio del programa (dos servidores de prueba que hablan entre sí) Cada vez consigo un número de objetos SAEA donde el .Buffer está completamente lleno de ceros, pero el .BytesTransferred es del tamaño del búfer (1024 en mi caso).

¿Qué significa esto? ¿Hay alguna condición especial que deba verificar? Mi sistema interpreta esto como un mensaje incompleto y continúa, pero me pregunto si realmente me faltan algunos datos. Tenía la impresión de que si no se recibía nada, no recibiría una devolución de llamada. En cualquier caso, puedo ver en WireShark que no hay ningún paquete de longitud cero entrando.

He encontrado lo siguiente cuando lo busqué en Google, pero no estoy seguro de que mi problema sea el mismo: http://social.msdn.microsoft.com/Forums/en-US/ncl/thread/40fe397c-b1da-428e-a355-ee5a6b0b4d2c

http://go4answers.webhost4life.com/Example/socketasynceventargs-buffer-not-ready-121918.aspx

+0

No he tenido ningún error de procesamiento de datos a causa de la pérdida de datos, por lo que creo que no se pierde nada. Pero eso todavía deja la pregunta de por qué el método volvería sin nada, varias veces. – Carlos

+1

Es difícil proporcionar la solución que necesita sin su breve descripción (con código). Sin embargo, tenía experiencia con Sockets y puedo recomendar el uso de una mayor abstracción: Network Stream. Network Stream tiene todas las capacidades de devolución de llamada Async que desea utilizar. Mire http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx y http://msdn.microsoft.com/en-us/library/system.net.sockets. networkstream.beginwrite.aspx HTH –

+0

¿Son las mismas llamadas subyacentes? Suena útil. Además, el código al que me refiero está en el enlace. – Carlos

Respuesta

0

estoy seguro que no lo que está pasando en el ejemplo enlazado. Parece estar utilizando conectores asíncronos de forma síncrona. No puedo ver ninguna devolución de llamada o similar en el código. Es posible que deba replantearse si necesita conectores síncronos o asincrónicos :).

El problema en cuestión surge de la posibilidad de que sus funciones intenten leer/escribir en el búfer antes de que se haya completado la transmisión/recepción de la red. Intente utilizar la funcionalidad de devolución de llamada incluida en el zócalo asincrónico. P.ej.

// This goes into your accept function, to begin receiving the data 
    socketName.BeginReceive(yourbuffer, 0, yourbuffer.Length, 
     SocketFlags.None, new AsyncCallback(OnRecieveData), socketName); 

// In your callback function you know that the socket has finished receiving data 
// This callback will fire when the receive is complete. 
private void OnRecieveData(IAsyncResult input) { 
    Socket inSocket = (Socket)input.AsyncState; // This is just a typecast 
    inSocket.EndReceive(input); 

    // Pull the data out of the socket as you already have before. 
    // state.Data.Write ...... 
} 
+0

Las devoluciones de llamada son los controladores de eventos en los objetos SAEA. De hecho, he ejecutado el código con algunos errores gramaticales mínimos. – Carlos

+0

Es posible que pegue el código de su receptor en pastebin o similar, solo he visto el ejemplo en el que se basa. – themartinmcfly

Cuestiones relacionadas