Función de devolución de llamada LPWSPSEND (ws2spi.h)
La función LPWSPSend envía datos en un socket conectado.
Sintaxis
LPWSPSEND Lpwspsend;
int Lpwspsend(
[in] SOCKET s,
[in] LPWSABUF lpBuffers,
[in] DWORD dwBufferCount,
[out] LPDWORD lpNumberOfBytesSent,
[in] DWORD dwFlags,
[in] LPWSAOVERLAPPED lpOverlapped,
[in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
[in] LPWSATHREADID lpThreadId,
[out] LPINT lpErrno
)
{...}
Parámetros
[in] s
Descriptor que identifica un socket conectado.
[in] lpBuffers
Puntero a una matriz de estructuras WSABUF . Cada estructura WSABUF contiene un puntero a un búfer y la longitud del búfer, en bytes. En el caso de una aplicación Winsock, una vez que se llama a la función LPWSPSend , el sistema posee estos búferes y es posible que la aplicación no tenga acceso a ellos. Los búferes de datos a los que se hace referencia en cada estructura WSABUF son propiedad del sistema y es posible que la aplicación no tenga acceso a ellos durante la duración de la llamada.
[in] dwBufferCount
Número de estructuras WSABUF en la matriz lpBuffers .
[out] lpNumberOfBytesSent
Puntero al número de bytes enviados por esta llamada.
[in] dwFlags
Conjunto de marcas que especifica la forma en que se realiza la llamada.
[in] lpOverlapped
Puntero a una estructura WSAOverlapped (omitida para sockets no superpuestos).
[in] lpCompletionRoutine
Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
Puntero a la rutina de finalización a la que se llama cuando se ha completado la operación de envío (se omite para sockets no superpuestos).
[in] lpThreadId
Puntero a una estructura WSATHREADID que usará el proveedor en una llamada posterior a WPUQueueApc. El proveedor debe almacenar la estructura WSATHREADID a la que se hace referencia (no el puntero a la misma) hasta después de que la función WPUQueueApc devuelva.
[out] lpErrno
Puntero al código de error.
Valor devuelto
Si no se produce ningún error y la operación de envío se ha completado inmediatamente, LPWSPSend devuelve cero. Tenga en cuenta que, en este caso, la rutina de finalización, si se especifica, ya se habrá puesto en cola. De lo contrario, se devuelve un valor de SOCKET_ERROR y hay disponible un código de error específico en lpErrno. El código de error WSA_IO_PENDING indica que la operación superpuesta se ha iniciado correctamente y que la finalización se indicará más adelante. Cualquier otro código de error indica que no se inició ninguna operación superpuesta y no se producirá ninguna indicación de finalización.
Código de error | Significado |
---|---|
Error en el subsistema de red. | |
La dirección solicitada es una dirección de difusión, pero no se estableció la marca adecuada. | |
El bloqueo de la llamada a Windows Sockets está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada. | |
El parámetro lpBuffers no está totalmente incluido en una parte válida del espacio de direcciones del usuario. | |
La conexión se ha interrumpido debido al restablecimiento del host remoto. | |
Se ha interrumpido la conexión debido a que la actividad para mantener activa la conexión detectó un error durante la operación. | |
socket no conectado. | |
El descriptor no es un socket. | |
MSG_OOB se especificó, pero el socket no es de estilo de flujo, como el tipo SOCK_STREAM, los datos OOB no se admiten en el dominio de comunicación asociado a este socket, MSG_PARTIAL no se admite o el socket es unidireccional y solo admite operaciones de recepción. | |
Se ha apagado el socket; no es posible LPWSPSend en un socket después de invocar LPWSPShutdown con cómo se establece en SD_SEND o SD_BOTH. | |
**Windows NT:** Sockets superpuestos: hay demasiadas solicitudes de E/S superpuestas pendientes. Sockets no superpuestos: el socket se marca como no desbloqueado y la operación de envío no se puede completar inmediatamente. | |
Socket está orientado a mensajes y el mensaje es mayor que el máximo admitido por el transporte subyacente. | |
El socket no se ha enlazado con LPWSPBind o el socket no se crea con la marca superpuesta. | |
Se finalizó el circuito virtual debido a un tiempo de espera u otro error. | |
El circuito virtual se restablece en el lado remoto. | |
La operación superpuesta se ha cancelado debido al cierre del socket o a la ejecución del comando SIO_FLUSH en LPWSPIoctl. |
Observaciones
La función LPWSPSend se usa para escribir datos salientes de uno o varios búferes en un socket orientado a la conexión especificado por s. Sin embargo, también se puede usar en sockets sin conexión que tengan una dirección del mismo nivel predeterminada estipulada establecida a través de la función LPWSPConnect .
En el caso de los sockets superpuestos (creados mediante LPWSPSocket con la marca WSA_FLAG_OVERLAPPED), esto se producirá mediante E/S superpuesta, a menos que lpOverlapped y lpCompletionRoutine sean null en cuyo caso el socket se trata como un socket no superpuesto. Se producirá una indicación de finalización (invocación de la rutina de finalización o configuración de un objeto de evento) cuando el transporte haya consumido los búferes proporcionados. Si la operación no se completa inmediatamente, el estado de finalización final se recupera a través de la rutina de finalización o LPWSPGetOverlappedResult.
En el caso de los sockets no superpuestos, los parámetros lpOverlapped, lpCompletionRoutine y lpThreadId se omiten y LPWSPSend adopta la semántica sincrónica normal. Los datos se copian de los búferes proporcionados en el búfer del transporte. Si el socket no está desbloqueado y orientado al flujo, y no hay suficiente espacio en el búfer del transporte, LPWSPSend devolverá solo con parte de los búferes proporcionados que se han consumido. Dada la misma situación de búfer y un socket de bloqueo, LPWSPSend se bloqueará hasta que se consuma todo el contenido del búfer proporcionado.
La matriz de estructuras WSABUF a las que apunta el parámetro lpBuffers es transitoria. Si esta operación se completa de forma superpuesta, es responsabilidad del proveedor de servicios capturar estas estructuras WSABUF antes de volver de esta llamada. Esto permite que las aplicaciones compilen matrices WSABUF basadas en pila.
En el caso de los sockets orientados a mensajes, se debe tener cuidado de no superar el tamaño máximo del mensaje del proveedor subyacente, que se puede obtener obteniendo el valor de la opción de socket SO_MAX_MSG_SIZE. Si los datos son demasiado largos para pasar de forma atómica a través del protocolo subyacente, se devuelve el error WSAEMSGSIZE y no se transmite ningún dato.
Tenga en cuenta que la finalización correcta de un LPWSPSend no indica que los datos se entregaron correctamente.
dwFlags se puede usar para influir en el comportamiento de la invocación de función más allá de las opciones especificadas para el socket asociado. Es decir, la semántica de esta función viene determinada por las opciones de socket y el parámetro dwFlags . Este último se construye mediante el operador OR bit a bit con cualquiera de los valores siguientes.
Value | Significado |
---|---|
MSG_DONTROUTE | Especifica que los datos no deben estar sujetos a enrutamiento. Un proveedor de servicios de Windows Sockets puede optar por omitir esta marca;. |
MSG_OOB | Envía datos OOB (socket de estilo de flujo, como solo SOCK_STREAM). |
MSG_PARTIAL | Especifica que lpBuffers solo contiene un mensaje parcial. Tenga en cuenta que el código de error WSAEOPNOTSUPP se devolverá para los mensajes que no admiten transmisiones parciales de mensajes. |
Si una operación superpuesta se completa inmediatamente, LPWSPSend devuelve un valor de cero y el parámetro lpNumberOfBytesSent se actualiza con el número de bytes enviados. Si la operación superpuesta se inicia correctamente y se completará más adelante, LPWSPSend devuelve SOCKET_ERROR e indica el código de error WSA_IO_PENDING. En este caso, lpNumberOfBytesSent no se actualiza. Cuando la operación superpuesta completa la cantidad de datos transferidos se indica a través del parámetro cbTransferred en la rutina de finalización (si se especifica) o a través del parámetro lpcbTransfer en LPWSPGetOverlappedResult.
Los proveedores deben permitir que se llame a esta función desde dentro de la rutina de finalización de una función LPWSPRecv, LPWSPRecvFrom, LPWSPSend o LPWSPSendTo . Sin embargo, para un socket determinado, las rutinas de finalización de E/S no se pueden anidar. Esto permite que las transmisiones de datos sensibles al tiempo se produzcan completamente dentro de un contexto preventivo.
El parámetro lpOverlapped debe ser válido durante la operación superpuesta. Si varias operaciones de E/S están pendientes simultáneamente, cada una debe hacer referencia a una estructura superpuesta independiente. La estructura WSAOverlapped se define en su propia página de referencia.
Si el parámetro lpCompletionRoutine es null, el proveedor de servicios señala al miembro hEvent de lpOverlapped cuando se completa la operación superpuesta si contiene un identificador de objeto de evento válido. El cliente SPI de Windows Sockets puede usar LPWSPGetOverlappedResult para esperar o sondear en el objeto de evento.
Si lpCompletionRoutine no es null, el miembro hEvent se omite y el cliente SPI de Windows Sockets puede usarse para pasar información de contexto a la rutina de finalización. Es posible que un cliente que pase un lpCompletionRoutine que no sea NULL y que posteriormente llame a WSAGetOverlappedResult para la misma solicitud de E/S superpuesta no puede establecer el parámetro fWait para esa invocación de WSAGetOverlappedResult en TRUE. En este caso, el uso del miembro hEvent no está definido y al intentar esperar en el miembro hEvent se generarían resultados impredecibles.
Un proveedor de servicios organiza una función que se va a ejecutar en el subproceso y el contexto de proceso adecuados mediante una llamada a WPUQueueApc. Se puede llamar a esta función desde cualquier contexto de proceso y subproceso, incluso un contexto diferente del subproceso y el proceso que se usó para iniciar la operación superpuesta.
Un proveedor de servicios organiza una función que se va a ejecutar en el subproceso adecuado mediante una llamada a WPUQueueApc. Tenga en cuenta que esta función debe invocarse mientras se encuentra en el contexto del mismo proceso (pero no necesariamente el mismo subproceso) que se usó para iniciar la operación superpuesta. Es responsabilidad del proveedor de servicios organizar este contexto de proceso para que esté activo antes de llamar a WPUQueueApc.
La función WPUQueueApc toma como parámetros de entrada un puntero a una estructura WSATHREADID (proporcionada al proveedor a través del parámetro de entrada lpThreadId ), un puntero a una función de APC que se va a invocar y un valor de contexto que se pasa posteriormente a la función de APC. Dado que solo hay disponible un único valor de contexto, la propia función de APC no puede ser la rutina de finalización especificada por el cliente. En su lugar, el proveedor de servicios debe proporcionar un puntero a su propia función de APC que usa el valor de contexto proporcionado para tener acceso a la información de resultado necesaria para la operación superpuesta y, a continuación, invoca la rutina de finalización especificada por el cliente.
El prototipo de la rutina de finalización proporcionada por el cliente es el siguiente.
void CALLBACK
CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine es un marcador de posición para un nombre de función proporcionado por el cliente. dwError especifica el estado de finalización de la operación superpuesta, como se indica en lpOverlapped. cbTransferred especifica el número de bytes enviados. No hay valores de marca definidos actualmente y el valor dwFlags será cero. Esta función no devuelve ningún valor.
Se puede llamar a las rutinas de finalización en cualquier orden, aunque no necesariamente en el mismo orden en que se completan las operaciones superpuestas. Sin embargo, el proveedor de servicios garantiza al cliente que los búferes publicados se envían en el mismo orden en que se suministran.
Nota
Todas las E/S iniciadas por un subproceso determinado se cancelan cuando se cierra ese subproceso. En el caso de los sockets superpuestos, las operaciones asincrónicas pendientes pueden producir un error si el subproceso está cerrado antes de que se completen las operaciones. Consulte ExitThread para obtener más información.
Requisitos
Cliente mínimo compatible | Windows 2000 Professional [solo aplicaciones de escritorio] |
Servidor mínimo compatible | Windows 2000 Server [solo aplicaciones de escritorio] |
Encabezado | ws2spi.h |