Compartir a través de


código de control de SIO_ASSOCIATE_PORT_RESERVATION

Descripción

El código de control SIO_ASSOCIATE_PORT_RESERVATION asocia un socket a una reserva persistente o en tiempo de ejecución para un bloque de TCP o UDP identificado por el token de reserva de puerto. Este IOCTL debe emitirse antes de que el socket esté enlazado. Si y cuando el socket está enlazado, el puerto asignado a él se seleccionará de la reserva de puertos identificada por el token especificado. Si no hay ningún puerto disponible en la reserva especificada, se producirá un error en la llamada a la función bind .

Para realizar esta operación, llame a la función WSAIoctl o WSPIoctl con los parámetros siguientes.

int WSAIoctl(
  (socket) s,             // descriptor identifying a socket
  SIO_ASSOCIATE_PORT_RESERVATION, // dwIoControlCode
  (LPVOID) lpvInBuffer,  // pointer to an INET_PORT_RESERVATION_TOKEN
  (DWORD) cbInBuffer,    // size, in bytes, of the input buffer
  NULL,           // lpvOutBuffer is a pointer to the output buffer
  0,              // cbOutBuffer is the size, in bytes, of the output buffer
  (LPDWORD) lpcbBytesReturned,    // number of bytes returned
  (LPWSAOVERLAPPED) lpOverlapped,   // OVERLAPPED structure
  (LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine,  // completion routine
);
int WSPIoctl(
  (socket) s,             // descriptor identifying a socket
  SIO_ASSOCIATE_PORT_RESERVATION, // dwIoControlCode
  (LPVOID) lpvInBuffer,  // pointer to an INET_PORT_RESERVATION_TOKEN
  (DWORD) cbInBuffer,    // size, in bytes, of the input buffer
  NULL,           // lpvOutBuffer is a pointer to the output buffer
  0,              // cbOutBuffer is the size, in bytes, of the output buffer
  (LPDWORD) lpcbBytesReturned,    // number of bytes returned
  (LPWSAOVERLAPPED) lpOverlapped,   // OVERLAPPED structure
  (LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine,  // completion routine
  (LPWSATHREADID) lpThreadId,   // a WSATHREADID structure
  (LPINT) lpErrno   // a pointer to the error code.
);

Parámetros

s

Descriptor que identifica un socket.

dwIoControlCode

Código de control para la operación. Use SIO_ASSOCIATE_PORT_RESERVATION para esta operación.

lpvInBuffer

Puntero al búfer de entrada. Este parámetro contiene un puntero a una estructura de INET_PORT_RESERVATION_TOKEN con el token de la reserva de puerto TCP o UDP que se va a asociar al socket.

cbInBuffer

Tamaño, en bytes, del búfer de entrada. Este parámetro debe tener al menos el tamaño de la estructura INET_PORT_RESERVATION_TOKEN .

lpvOutBuffer

Puntero al búfer de salida. Este parámetro no se usa para esta operación.

cbOutBuffer

Tamaño, en bytes, del búfer de salida. Este parámetro debe establecerse en cero.

lpcbBytesReturned

Puntero a una variable que recibe el tamaño, en bytes, de los datos almacenados en el búfer de salida.

Si el búfer de salida es demasiado pequeño, se produce un error en la llamada, WSAGetLastError devuelve WSAEINVAL y el parámetro lpcbBytesReturned apunta a un valor DWORD de cero.

Si lpOverlapped es NULL, el valor DWORD al que apunta el parámetro lpcbBytesReturned que se devuelve en una llamada correcta no puede ser cero.

Si el parámetro lpOverlapped no es NULL para sockets superpuestos, las operaciones que no se pueden completar inmediatamente se iniciarán y la finalización se indicará más adelante. El valor DWORD al que apunta el parámetro lpcbBytesReturned devuelto puede ser cero, ya que el tamaño de los datos almacenados no se puede determinar hasta que se haya completado la operación superpuesta. El estado de finalización final se puede recuperar cuando se señala el método de finalización adecuado cuando se ha completado la operación.

lpvOverlapped

Puntero a una estructura WSAOVERLAPPED .

Si el socket se creó sin el atributo superpuesto, se omite el parámetro lpOverlapped .

Si se abrió con el atributo superpuesto y el parámetro lpOverlapped no es NULL, la operación se realiza como una operación superpuesta (asincrónica). En este caso, el parámetro lpOverlapped debe apuntar a una estructura WSAOVERLAPPED válida.

En el caso de las operaciones superpuestas, la función WSAIoctl o WSPIoctl devuelve inmediatamente y el método de finalización adecuado se señala cuando se ha completado la operación. De lo contrario, la función no devuelve hasta que se haya completado la operación o se produzca un error.

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 (se omite para sockets no superpuestos).

lpThreadId

Puntero a una estructura WSATHREADID que va a 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 que se devuelva la función WPUQueueApc .

Nota Este parámetro solo se aplica a la función WSPIoctl .

lpErrno

Puntero al código de error.

Nota Este parámetro solo se aplica a la función WSPIoctl .

Valor devuelto

Si la operación se completa correctamente, la función WSAIoctl o WSPIoctl devuelve cero.

Si se produce un error en la operación o está pendiente, la función WSAIoctl o WSPIoctl devuelve SOCKET_ERROR. Para obtener información de error extendida, llame a WSAGetLastError.

Código de error Significado
WSA_IO_PENDING La operación de E/S superpuesta está en curso. Este valor se devuelve si se inició correctamente una operación superpuesta y la finalización se indicará en un momento posterior.
WSA_OPERATION_ABORTED Se ha anulado la operación de E/S debido a una solicitud de la aplicación o una salida del subproceso. Este error se devuelve si se canceló una operación superpuesta debido al cierre del socket o a la ejecución del comando SIO_FLUSH IOCTL .
WSAEACCES Se intentó acceder a un socket de una manera prohibida por sus permisos de acceso. Este error se devuelve en varias condiciones para las reservas de puertos persistentes que incluyen lo siguiente: el usuario carece de los privilegios administrativos necesarios en el equipo local o la aplicación no se ejecuta en un shell mejorado como administrador integrado (RunAs administrator).
WSAEFAULT El sistema detectó una dirección de puntero no válida al intentar usar un argumento de puntero en una llamada. Este error se devuelve del parámetro lpvInBuffer, lpvoutBuffer, lpcbBytesReturned, lpOverlapped o lpCompletionRoutine no está totalmente incluido en una parte válida del espacio de direcciones del usuario.
WSAEINPROGRESS Se está ejecutando una operación de bloqueo actualmente. Este error se devuelve si se invoca la función cuando hay una devolución de llamada en curso.
WSAEINTR Una operación de bloqueo se interrumpió mediante una llamada a WSACancelBlockingCall. Este error se devuelve si se interrumpió una operación de bloqueo.
WSAEINVAL Se proporcionó un argumento no válido. Este error se devuelve si el parámetro dwIoControlCode no es un comando válido o si un parámetro de entrada especificado no es aceptable o el comando no es aplicable al tipo de socket especificado.
WSAENETDOWN Una operación de socket encontró una red inactiva. Este error se devuelve si se ha producido un error en el subsistema de red.
WSAENOTSOCK Se intentó realizar una operación en algo que no es un socket. Este error se devuelve si el descriptor s no es un socket.
WSAEOPNOTSUPP La operación intentada no se admite para el tipo de objeto al que se hace referencia. Este error se devuelve si no se admite el comando IOCTL especificado. Este error también se devuelve si el proveedor de transporte no admite el SIO_ASSOCIATE_PORT_RESERVATION IOCTL. Este error también se devuelve cuando se intenta usar el SIO_ASSOCIATE_PORT_RESERVATION IOCTL en un socket distinto de UDP o TCP.

Observaciones

El SIO_ASSOCIATE_PORT_RESERVATION IOCTL es compatible con Windows Vista y versiones posteriores del sistema operativo.

Las aplicaciones y los servicios que necesitan reservar puertos se dividen en dos categorías. La primera categoría incluye componentes que necesitan un puerto determinado como parte de su operación. Por lo general, estos componentes prefieren especificar su puerto necesario en el momento de la instalación (por ejemplo, en un manifiesto de aplicación). La segunda categoría incluye componentes que necesitan cualquier puerto o bloque de puertos disponibles en tiempo de ejecución. Estas dos categorías corresponden a solicitudes de reserva de puertos comodín y específicas. Las solicitudes de reserva específicas pueden ser persistentes o en tiempo de ejecución, mientras que las solicitudes de reserva de puerto comodín solo se admiten en tiempo de ejecución.

El SIO_ASSOCIATE_PORT_RESERVATION IOCTL se usa para asociar una reserva de puertos TCP o UDP a una reserva de tiempo de ejecución o persistente.

La función CreatePersistentTcpPortReservation o CreatePersistentUdpPortReservation proporciona la posibilidad de que una aplicación o servicio reserve un bloque persistente de puertos TCP o UDP. Las reservas de puertos persistentes se registran en un almacén persistente para el módulo TCP o UDP en Windows. Tenga en cuenta que el token de una reserva de puerto persistente determinada puede cambiar cada vez que se reinicia el sistema.

Una vez que se ha obtenido una reserva de puertos TCP o UDP persistente, una aplicación puede solicitar asignaciones de puerto desde la reserva de puertos abriendo un socket TCP o UDP y, a continuación, llamando a la función WSAIoctl especificando el SIO_ASSOCIATE_PORT_RESERVATION IOCTL y pasando el token de reserva antes de emitir una llamada a la función bind en el socket.

El SIO_ACQUIRE_PORT_RESERVATION IOCTL se puede usar para solicitar una reserva en tiempo de ejecución para un bloque de puertos TCP o UDP. Para las reservas de puertos en tiempo de ejecución, el grupo de puertos requiere que las reservas se consuman desde el proceso en cuyo socket se concedió la reserva. Las reservas de puertos en tiempo de ejecución solo duran mientras dure el socket en el que se llamó al SIO_ACQUIRE_PORT_RESERVATION IOCTL. En cambio, las reservas de puertos persistentes creadas mediante la función CreatePersistentTcpPortReservation o CreatePersistentUdpPortReservation pueden consumirse por cualquier proceso con la capacidad de obtener reservas persistentes.

Una vez que se ha obtenido una reserva de puertos TCP o UDP en tiempo de ejecución, una aplicación puede solicitar asignaciones de puertos de la reserva de puertos abriendo un socket TCP o UDP y, a continuación, llamando a la función WSAIoctl especificando el SIO_ASSOCIATE_PORT_RESERVATION IOCTL y pasando el token de reserva antes de emitir una llamada a la función bind en el socket.

Si los parámetros lpOverlapped y lpCompletionRoutine son NULL, el socket de esta función se tratará como un socket no superpuesto. En el caso de un socket no superpuesto, se omiten los parámetros lpOverlapped y lpCompletionRoutine , salvo que la función puede bloquearse si el socket s está en modo de bloqueo. Si el socket s está en modo de no bloqueo, esta función se bloqueará, ya que este IOCTL determinado no admite el modo de no bloqueo.

En el caso de sockets superpuestos, las operaciones que no se pueden completar inmediatamente se iniciarán y la finalización se indicará más adelante.

Cualquier IOCTL puede bloquearse indefinidamente, dependiendo de la implementación del proveedor de servicios. Si la aplicación no puede tolerar el bloqueo en una llamada de función WSAIoctl o WSPIoctl , se recomienda que las E/S superpuestas se bloqueen en las E/S superpuestas.

El SIO_ASSOCIATE_PORT_RESERVATION IOCTL puede producir un error con WSAEINTR o WSA_OPERATION_ABORTED en los casos siguientes:

  • El Administrador de E/S cancela la solicitud.
  • El socket está cerrado.

El SIO_ASSOCIATE_PORT_RESERVATION IOCTL pasado a la función WSAIoctl o WSPIoctl para una reserva de puerto persistente solo se puede usar en una aplicación cuando el usuario ha iniciado sesión como miembro del grupo Administradores. Si SIO_ASSOCIATE_PORT_RESERVATION IOCTL se usa en una aplicación cuando el usuario no es miembro del grupo Administradores, se producirá un error en la llamada de función y se devolverá WSAEACCES . El uso del SIO_ASSOCIATE_PORT_RESERVATION IOCTL también puede producir un error debido al control de cuentas de usuario (UAC) en Windows Vista y versiones posteriores. Si una aplicación que usa este IOCTL con una reserva de puertos persistente se ejecuta mediante un usuario que ha iniciado sesión como miembro del grupo Administradores distinto del administrador integrado, esta llamada producirá un error a menos que la aplicación se haya marcado en el archivo de manifiesto con un valor requestedExecutionLevel establecido en requireAdministrator. Si la aplicación carece de este archivo de manifiesto, un usuario que inició sesión como miembro del grupo Administradores distinto del administrador integrado debe ejecutar la aplicación en un shell mejorado como administrador integrado (RunAs administrator) para que esta función se realice correctamente.

Vea también

Atar

CreatePersistentTcpPortReservation

CreatePersistentUdpPortReservation

DeletePersistentTcpPortReservation

DeletePersistentUdpPortReservation

INET_PORT_RESERVATION_TOKEN

LookupPersistentTcpPortReservation

LookupPersistentUdpPortReservation

SIO_ACQUIRE_PORT_RESERVATION

SIO_RELEASE_PORT_RESERVATION

socket

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAOVERLAPPED

WSASocketA

WSASocketW