socket c#
¿Se puede completar una operación TCP Socket SendAsync sin transferir todos los bytes en un BufferList? (2)
¿Qué estás tratando de comprobar aquí? ¿Le preocupa por qué no recibe todos los bytes cuando se envían todos los bytes?
Cuando envía 100 bytes de una vez e intenta leer 100 bytes en el otro extremo, no hay garantía de que recibirá todos los bytes de una sola vez. Se podría dividir en 100 paquetes de 1 byte. Así es como funciona el TCP. Siempre debe acumular bytes y luego formar y separar sus paquetes. Eso se llama esfuerzo de plomería TCP socket. WCF y todos esos envoltorios lo hacen por ti.
En Mono 3.12, estoy usando Socket.SendAsync(SocketAsyncEventArgs)
con un TCP Stream Socket
para implementar un protocolo de transmisión basado en solicitudes. Estoy usando SocketAsyncEventArgs.BufferList
para configurar múltiples buffers de datos.
En la documentación de Socket
y SocketAsyncEventArgs
, no puedo encontrar ninguna mención de si el SocketAsyncEventArgs puede levantarse sin que se envíen todos los bytes cuando se utiliza BufferList
, dejando la impresión de que tenemos que validar contra SocketAsyncEventArgs.BytesTransferred
.
Por otro lado, Socket.BeginSend
hace esa garantía.
Cuando su aplicación llama a
BeginSend
, el sistema usará un hilo separado para ejecutar el método de devolución de llamada especificado, y se bloqueará enEndSend
hasta que elSocket
envíe el número de bytes solicitados o arroje una excepción.
¿Qué garantías tiene la especificación sobre el número de bytes transferidos cuando se usa SendAsync
con un SocketAsyncEventArgs.BufferList
?
Supongamos que el evento se completó con SocketError.Success
.
¿Qué garantías tiene la especificación sobre el número de bytes transferidos cuando se usa SendAsync con un SocketAsyncEventArgs.BufferList
?
Para empezar, el evento puede generarse por errores, en cuyo caso puede suponer que no se han transferido todos los bytes. Para ello, debe probar SocketAsyncEventArgs.SocketError para SocketError.Success. Además, si se refiere a ''especificación'', asumo que se refiere a la documentación de Windows (Sockets) de Windows (ya que se vincula a esto para SendAsync y otras descripciones).
También debe hacer algunos pasos para establecer lo que dice o implica la documentación sobre el número de bytes transferidos cuando se llama al evento Completado en caso de éxito. El primer paso es ver si SendAsync usa E / S superpuesta. Esa pregunta se responde en la documentación de entrada / salida superpuesta . La implementación de este mecanismo es obligatoria para los proveedores de transporte subyacentes y, por lo tanto, es el único mecanismo de E / S superpuesto que se garantiza que esté disponible para Windows Sockets. Como tal, se garantiza que SendAsync utiliza un socket con el atributo WSA_FLAG_OVERLAPPED.
Tenga en cuenta que la inspección de la implementación de referencia de SendAsync muestra que SendAsync de hecho está utilizando WSASend con E / S superpuesta, pero eso es simplemente una observación.
El segundo paso es determinar qué E / S superpuesta nos dice acerca de la señalización del evento completado en relación con la cantidad de bytes transferidos. Esta situación se describe en varios lugares, por ejemplo, en esta página de I / I y objetos de evento superpuestos : ''se proporcionará una indicación cuando se hayan consumido los buffers de envío''. Se proporciona un poco más de detalle en la sección de comentarios para la función [WSASend]: ''Ocurrirá una indicación de finalización, invocando la finalización de una rutina o configuración de un objeto de evento, cuando el transporte ha consumido los búferes'' .
Esto todavía deja espacio para la interpretación exacta de esta frase. Básicamente, dice que los datos fueron aceptados y confirmados por un mecanismo de transporte subyacente fuera del alcance del socket. Esto no significa necesariamente que haya llegado a la capa del protocolo de punto final remoto, esto dependería del protocolo de comunicación. Para un socket de transmisión TCP, inferiría que indica que los datos llegaron al punto final remoto.
La conclusión aquí es que la documentación garantiza (para una situación sin error) que el evento completado SendAsync se genera solo en el momento en que todos los bytes se han transferido.