Función socket (winsock2.h)
La función socket crea un socket enlazado a un proveedor de servicios de transporte específico.
Sintaxis
SOCKET WSAAPI socket(
[in] int af,
[in] int type,
[in] int protocol
);
Parámetros
[in] af
Especificación de la familia de direcciones. Los valores posibles para la familia de direcciones se definen en el archivo de encabezado Winsock2.h .
En el Windows SDK publicado para Windows Vista y versiones posteriores, la organización de los archivos de encabezado ha cambiado y los valores posibles para la familia de direcciones se definen en el archivo de encabezado Ws2def.h. Tenga en cuenta que el archivo de encabezado Ws2def.h se incluye automáticamente en Winsock2.h y nunca se debe usar directamente.
Los valores admitidos actualmente son AF_INET o AF_INET6, que son los formatos de familia de direcciones de Internet para IPv4 e IPv6. Se admiten otras opciones para la familia de direcciones (AF_NETBIOS para su uso con NetBIOS, por ejemplo) si se instala un proveedor de servicios de Windows Sockets para la familia de direcciones. Tenga en cuenta que los valores de la familia de direcciones AF_ y las constantes de familia de protocolos PF_ son idénticas (por ejemplo, AF_INET y PF_INET), por lo que se puede usar cualquiera de las constantes.
En la tabla siguiente se enumeran los valores comunes de la familia de direcciones, aunque muchos otros valores son posibles.
Af | Significado |
---|---|
|
No se especifica la familia de direcciones. |
|
Familia de direcciones del Protocolo de Internet versión 4 (IPv4). |
|
Familia de direcciones IPX/SPX. Esta familia de direcciones solo se admite si está instalado el protocolo de transporte compatible con NWLink IPX/SPX NetBIOS.
Esta familia de direcciones no se admite en Windows Vista y versiones posteriores. |
|
Familia de direcciones de AppleTalk. Esta familia de direcciones solo se admite si está instalado el protocolo AppleTalk.
Esta familia de direcciones no se admite en Windows Vista y versiones posteriores. |
|
Familia de direcciones NetBIOS. Esta familia de direcciones solo se admite si está instalado el proveedor de Windows Sockets para NetBIOS.
El proveedor de Windows Sockets para NetBIOS es compatible con versiones de 32 bits de Windows. Este proveedor se instala de forma predeterminada en versiones de 32 bits de Windows. El proveedor de Windows Sockets para NetBIOS no se admite en versiones de 64 bits de windows, como Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 o Windows XP. El proveedor de Windows Sockets para NetBIOS solo admite sockets en los que el parámetro de tipo se establece en SOCK_DGRAM. El proveedor de Windows Sockets para NetBIOS no está relacionado directamente con la interfaz de programación netBIOS . La interfaz de programación NetBIOS no se admite en Windows Vista, Windows Server 2008 y versiones posteriores. |
|
Familia de direcciones del Protocolo de Internet versión 6 (IPv6). |
|
Familia de direcciones de la Asociación de datos infrarrojos (IrDA).
Esta familia de direcciones solo se admite si el equipo tiene instalado un puerto infrarrojo y un controlador. |
|
La familia de direcciones Bluetooth.
Esta familia de direcciones es compatible con Windows XP con SP2 o posterior si el equipo tiene instalado un adaptador y un controlador Bluetooth. |
[in] type
Especificación de tipo para el nuevo socket.
Los valores posibles para el tipo de socket se definen en el archivo de encabezado Winsock2.h .
En la tabla siguiente se enumeran los valores posibles para el parámetro de tipo admitido para Windows Sockets 2:
Tipo | Significado |
---|---|
|
Tipo de socket que proporciona flujos de bytes secuenciados, confiables, bidireccionales y basados en conexiones con un mecanismo de transmisión de datos OOB. Este tipo de socket usa el Protocolo de control de transmisión (TCP) para la familia de direcciones de Internet (AF_INET o AF_INET6). |
|
Tipo de socket que admite datagramas, que son a menos que los búferes no confiables de una longitud máxima fija (normalmente pequeña). Este tipo de socket usa el Protocolo de datagramas de usuario (UDP) para la familia de direcciones de Internet (AF_INET o AF_INET6). |
|
Tipo de socket que proporciona un socket sin formato que permite a una aplicación manipular el siguiente encabezado de protocolo de capa superior. Para manipular el encabezado IPv4, la opción de socket IP_HDRINCL debe establecerse en el socket. Para manipular el encabezado IPv6, la opción de socket IPV6_HDRINCL debe establecerse en el socket. |
|
Tipo de socket que proporciona un datagrama de mensaje confiable. Un ejemplo de este tipo es la implementación del protocolo de multidifusión general pragmática (PGM) en Windows, a menudo denominada programación de multidifusión confiable.
Este valor de tipo solo se admite si está instalado el Protocolo de multidifusión confiable. |
|
Tipo de socket que proporciona un paquete pseudo-stream basado en datagramas. |
En Windows Sockets 2, se introdujeron nuevos tipos de socket. Una aplicación puede detectar dinámicamente los atributos de cada protocolo de transporte disponible a través de la función WSAEnumProtocols . Por lo tanto, una aplicación puede determinar las posibles opciones de tipo de socket y protocolo para una familia de direcciones y usar esta información al especificar este parámetro. Las definiciones de tipo de socket en los archivos de encabezado Winsock2.h y Ws2def.h se actualizarán periódicamente a medida que se definen nuevos tipos de socket, familias de direcciones y protocolos.
En Windows Sockets 1.1, los únicos tipos de socket posibles son SOCK_DGRAM y SOCK_STREAM.
[in] protocol
Protocolo que se va a usar. Las opciones posibles para el parámetro de protocolo son específicas de la familia de direcciones y el tipo de socket especificados. Los valores posibles para el protocolo se definen en los archivos de encabezado Winsock2.h y Wsrm.h .
En el Windows SDK publicado para Windows Vista y versiones posteriores, la organización de los archivos de encabezado ha cambiado y este parámetro puede ser uno de los valores del tipo de enumeración IPPROTO definido en el archivo de encabezado Ws2def.h. Tenga en cuenta que el archivo de encabezado Ws2def.h se incluye automáticamente en Winsock2.h y nunca se debe usar directamente.
Si se especifica un valor de 0, el autor de la llamada no desea especificar un protocolo y el proveedor de servicios elegirá el protocolo que se va a usar.
Cuando el parámetro af se AF_INET o AF_INET6 y el tipo se SOCK_RAW, el valor especificado para el protocolo se establece en el campo de protocolo del encabezado de paquete IPv6 o IPv4.
En la tabla siguiente se enumeran los valores comunes para el protocolo , aunque muchos otros valores son posibles.
Valor devuelto
Si no se produce ningún error, socket devuelve un descriptor que hace referencia al nuevo socket. De lo contrario, se devuelve un valor de INVALID_SOCKET y se puede recuperar un código de error específico mediante una llamada a WSAGetLastError.
Código de error | Significado |
---|---|
Debe producirse una llamada WSAStartup correcta antes de usar esta función. | |
Error en el subsistema de red o en el proveedor de servicios asociado. | |
La familia de direcciones especificada no se admite. Por ejemplo, una aplicación intentó crear un socket para la familia de direcciones AF_IRDA , pero un adaptador de infrarrojos y un controlador de dispositivo no está instalado en el equipo local. | |
Una llamada de Bloqueo de Windows Sockets 1.1 está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada. | |
No hay más descriptores de socket disponibles. | |
Se ha proporcionado un argumento no válido. Este error se devuelve si el parámetro af se establece en AF_UNSPEC y el tipo y el parámetro de protocolo no se especifican. | |
El proveedor de servicios devolvió una versión distinta de la 2.2. | |
El proveedor de servicios devolvió una tabla de procedimientos no válida o incompleta al WSPStartup. | |
No hay espacio disponible en el búfer. El socket no se puede crear. | |
No se admite el protocolo especificado. | |
El protocolo especificado es el tipo incorrecto para este socket. | |
No se pudo inicializar el proveedor de servicios. Este error se devuelve si un proveedor de servicios en capas (LSP) o proveedor de espacios de nombres se instaló incorrectamente o el proveedor no funciona correctamente. | |
El tipo de socket especificado no se admite en esta familia de direcciones. |
Comentarios
La función de socket hace que un descriptor de socket y los recursos relacionados se asignen y se enlacen a un proveedor de servicios de transporte específico. Winsock usará el primer proveedor de servicios disponible que admite la combinación solicitada de familia de direcciones, tipo de socket y parámetros de protocolo. El socket que se crea tendrá el atributo superpuesto como valor predeterminado. Para Windows, la opción de socket específico de Microsoft, SO_OPENTYPE, definida en Mswsock.h puede afectar a este valor predeterminado. Consulte la documentación específica de Microsoft para obtener una descripción detallada de SO_OPENTYPE.
Los sockets sin el atributo superpuesto se pueden crear mediante WSASocket. Todas las funciones que permiten la operación superpuesta (WSASend, WSARecv, WSASendTo, WSARecvFrom y WSAIoctl) también admiten el uso no superpuesto en un socket superpuesto si los valores de los parámetros relacionados con la operación superpuesta son NULL.
Al seleccionar un protocolo y su proveedor de servicios auxiliar, este procedimiento solo elegirá un protocolo base o una cadena de protocolos, no una capa de protocolo por sí misma. Las capas de protocolo no encadenadas no se consideran coincidencias parciales en el tipo o af . Es decir, no conducen a un código de error de WSAEAFNOSUPPORT o WSAEPROTONOSUPPORT si no se encuentra ningún protocolo adecuado.
Los sockets orientados a la conexión, como SOCK_STREAM proporcionan conexiones dúplex completas, y deben estar en un estado conectado antes de que se puedan enviar o recibir datos en él. Se crea una conexión a otro socket con una llamada de conexión . Una vez conectado, los datos se pueden transferir mediante llamadas de envío y recv . Cuando se ha completado una sesión, se debe realizar un closesocket .
Los protocolos de comunicaciones usados para implementar un socket confiable orientado a la conexión garantizan que los datos no se pierdan o dupliquen. Si los datos para los que el protocolo del mismo nivel tiene espacio de búfer no se pueden transmitir correctamente dentro de un período razonable de tiempo, la conexión se considera interrumpida y las llamadas posteriores producirán un error con el código de error establecido en WSAETIMEDOUT.
Los sockets orientados a mensajes sin conexión permiten enviar y recibir datagramas hacia y desde elementos del mismo nivel arbitrarios mediante sendto y recvfrom. Si este socket está conectado a un mismo nivel específico, los datagramas se pueden enviar a ese mismo nivel mediante send y solo se pueden recibir de este mismo nivel mediante recv.
IPv6 e IPv4 funcionan de forma diferente al recibir un socket con un tipo de SOCK_RAW. El paquete de recepción IPv4 incluye la carga del paquete, el siguiente encabezado de nivel superior (por ejemplo, el encabezado IP de un paquete TCP o UDP) y el encabezado de paquete IPv4. El paquete de recepción IPv6 incluye la carga del paquete y el siguiente encabezado de nivel superior. El paquete de recepción IPv6 nunca incluye el encabezado de paquete IPv6.
Cuando el parámetro af es AF_NETBIOS para NetBIOS a través de TCP/IP, el parámetro de tipo puede ser SOCK_DGRAM o SOCK_SEQPACKET. Para la familia de direcciones de AF_NETBIOS , el parámetro de protocolo es el número de adaptador de LAN representado como un número negativo.
En Windows XP y versiones posteriores, se puede usar el siguiente comando para enumerar el catálogo de Windows Sockets para determinar los proveedores de servicios instalados y la familia de direcciones, el tipo de socket y los protocolos admitidos.
netsh winsock show catalog
No se requiere compatibilidad con sockets con SOCK_RAW de tipo, pero se recomienda a los proveedores de servicios que admitan sockets sin procesar como factibles.
Notas para sockets irDA
Tenga en cuenta lo siguiente:- El archivo de encabezado Af_irda.h debe incluirse explícitamente.
- Solo se admite SOCK_STREAM ; IrDA no admite el tipo SOCK_DGRAM .
- El parámetro de protocolo siempre se establece en 0 para IrDA.
Código de ejemplo
En el ejemplo siguiente se muestra el uso de la función de socket para crear un socket enlazado a un proveedor de servicios de transporte específico.#ifndef UNICODE
#define UNICODE 1
#endif
// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h> // Needed for _wtoi
int __cdecl wmain(int argc, wchar_t **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData = {0};
int iResult = 0;
// int i = 1;
SOCKET sock = INVALID_SOCKET;
int iFamily = AF_UNSPEC;
int iType = 0;
int iProtocol = 0;
// Validate the parameters
if (argc != 4) {
wprintf(L"usage: %s <addressfamily> <type> <protocol>\n", argv[0]);
wprintf(L"socket opens a socket for the specified family, type, & protocol\n");
wprintf(L"%ws example usage\n", argv[0]);
wprintf(L" %ws 0 2 17\n", argv[0]);
wprintf(L" where AF_UNSPEC=0 SOCK_DGRAM=2 IPPROTO_UDP=17\n", argv[0]);
return 1;
}
iFamily = _wtoi(argv[1]);
iType = _wtoi(argv[2]);
iProtocol = _wtoi(argv[3]);
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed: %d\n", iResult);
return 1;
}
wprintf(L"Calling socket with following parameters:\n");
wprintf(L" Address Family = ");
switch (iFamily) {
case AF_UNSPEC:
wprintf(L"Unspecified");
break;
case AF_INET:
wprintf(L"AF_INET (IPv4)");
break;
case AF_INET6:
wprintf(L"AF_INET6 (IPv6)");
break;
case AF_NETBIOS:
wprintf(L"AF_NETBIOS (NetBIOS)");
break;
case AF_BTH:
wprintf(L"AF_BTH (Bluetooth)");
break;
default:
wprintf(L"Other");
break;
}
wprintf(L" (%d)\n", iFamily);
wprintf(L" Socket type = ");
switch (iType) {
case 0:
wprintf(L"Unspecified");
break;
case SOCK_STREAM:
wprintf(L"SOCK_STREAM (stream)");
break;
case SOCK_DGRAM:
wprintf(L"SOCK_DGRAM (datagram)");
break;
case SOCK_RAW:
wprintf(L"SOCK_RAW (raw)");
break;
case SOCK_RDM:
wprintf(L"SOCK_RDM (reliable message datagram)");
break;
case SOCK_SEQPACKET:
wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)");
break;
default:
wprintf(L"Other");
break;
}
wprintf(L" (%d)\n", iType);
wprintf(L" Protocol = %d = ", iProtocol);
switch (iProtocol) {
case 0:
wprintf(L"Unspecified");
break;
case IPPROTO_ICMP:
wprintf(L"IPPROTO_ICMP (ICMP)");
break;
case IPPROTO_IGMP:
wprintf(L"IPPROTO_IGMP (IGMP)");
break;
case IPPROTO_TCP:
wprintf(L"IPPROTO_TCP (TCP)");
break;
case IPPROTO_UDP:
wprintf(L"IPPROTO_UDP (UDP)");
break;
case IPPROTO_ICMPV6:
wprintf(L"IPPROTO_ICMPV6 (ICMP Version 6)");
break;
default:
wprintf(L"Other");
break;
}
wprintf(L" (%d)\n", iProtocol);
sock = socket(iFamily, iType, iProtocol);
if (sock == INVALID_SOCKET)
wprintf(L"socket function failed with error = %d\n", WSAGetLastError() );
else {
wprintf(L"socket function succeeded\n");
// Close the socket to release the resources associated
// Normally an application calls shutdown() before closesocket
// to disables sends or receives on a socket first
// This isn't needed in this simple sample
iResult = closesocket(sock);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error = %d\n", WSAGetLastError() );
WSACleanup();
return 1;
}
}
WSACleanup();
return 0;
}
Windows Phone 8: esta función es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.
Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP] |
Servidor mínimo compatible | Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP] |
Plataforma de destino | Windows |
Encabezado | winsock2.h |
Library | Ws2_32.lib |
Archivo DLL | Ws2_32.dll |
Consulte también
Opciones de socket de IPPROTO_IP
Opciones de socket de IPPROTO_IPV6