Uso de la API de Winsocket
1. Introducción a WinSock
Socket (socket) fue originalmente una interfaz de comunicación de red desarrollada por la Universidad de California, Berkeley (Berkeley) para el sistema operativo UNIX con un uso generalizado. En UNIX, Socket se ha convertido en una de las interfaces de aplicaciones de comunicación de red más populares. A principios de la década de 1990, varias empresas, entre ellas Sun Microsystems, JSB, FTP software, Microdyne y Microsoft, personalizaron conjuntamente un conjunto de estándares, concretamente la especificación Windows Socket, conocida como WinSock.
Hay dos formas principales de escribir programas de red en VB: 1.control winsock 2.winsockAPI
En segundo lugar, el uso del control WinSock
1.El Características principales de las propiedades del control WinSock
a.Propiedad de protocolo
La propiedad Protocolo se puede utilizar para configurar el protocolo utilizado por el control WinSock para conectarse a la computadora remota. Los protocolos opcionales son TCP y UDP. Las constantes de VB correspondientes son sckTCPProtocol y sckUDPProtocol respectivamente. El protocolo predeterminado del control Winsock es TCP. Nota: Aunque el protocolo se puede configurar en tiempo de ejecución, debe hacerlo después de que la conexión no se establezca o se desconecte.
b.Propiedad SocketHandle
SocketHandle devuelve el identificador de la conexión de socket actual. Esta es una propiedad de solo lectura.
Propiedad c.RemoteHostIP
La propiedad RemoteHostIP devuelve la dirección IP del ordenador remoto. En el lado del cliente, cuando se utiliza el método Connect del control, la dirección IP de la computadora remota se asigna a la propiedad RemoteHostIP, y en el lado del servidor, cuando ocurre el evento ConnectRequest, la dirección IP de la computadora remota (cliente ) está asignado a esta propiedad. Si se utiliza el protocolo UDP, después del evento DataArrival, la IP de la computadora que envía el mensaje UDP se asigna a este atributo.
Propiedad d.ByteReceived
Devuelve el número de bytes en el buffer de recepción actual
Propiedad e.State
Devuelve el valor actual del control WinSock Estado
Descripción del valor constante
sckClosed 0 Valor predeterminado, cerrado.
SckOpen 1 Abierto.
SckListening 2 Escuchando
sckConnectionPending 3 Conexión pendiente
sckResolvingHost 4 Identificando el host.
sckHostResolved 5 Host reconocido
sckConnecting 6 Conectando.
sckConnected 7 Conectado.
sckClosing 8 El interlocutor está cerrando la conexión.
Error sckError 9
2.Método principal de WinSock
Método a.Bind
Utilice el método Bind para corregir un número de puerto como El uso de este control evita que otras aplicaciones utilicen este puerto.
b.Método Listen
El método Listen solo es útil cuando se utiliza el protocolo TCP. Pone la aplicación en un estado de detección de escucha.
c.Método Connect
Cuando la computadora local desea establecer una conexión con la computadora remota, puede llamar al método Connect.
La especificación para llamar al método Connect es:
Connect RemoteHost,RemotePort
método d.Accept
Cuando el servidor recibe el conexión del cliente Después de la solicitud, el servidor tiene derecho a decidir si acepta la solicitud del cliente.
Método e.SendData
Cuando se establece la conexión, puede llamar al método SendData para enviar datos. Este método tiene un solo parámetro, que son los datos a enviar.
Método f.GetData
Cuando la computadora local recibe datos de la computadora remota, los datos se almacenan en el búfer. Para recuperar los datos del búfer, puede usar GetData. método. La especificación de llamada al método GetData es la siguiente:
GetData data,[type,][maxLen]
Obtiene los datos hasta maxLen del búfer y los almacena en datos en el escriba tipo, después de que GetData obtenga los datos, se borrará el búfer correspondiente.
Método g.PeekData
Similar al método GetData, pero PeekData no borra el búfer después de obtener los datos.
3.Eventos principales del control Winsock
a.Evento ConnectRequest
Cuando la computadora local recibe una solicitud de conexión enviada por la computadora remota, el evento ConnectRequest del control se desencadena.
b.Evento SendProgress
Cuando la computadora en un extremo envía datos a la computadora en el otro extremo, se activará el evento SendProgress. El evento SendProgress registra la cantidad de bytes enviados y la cantidad de bytes restantes en el estado actual.
evento c.SendComplete
Se activa cuando se envían todos los datos.
Evento d.DataArrival
Este evento se activará cuando se reciban nuevos datos después de que se establezca la conexión. Nota: Si el búfer no está vacío antes de recibir nuevos datos, este evento no se activará.
e.Evento de error
Este evento se activará cuando ocurra algún error durante el trabajo.
Vea el archivo adjunto para ver ejemplos
3. Uso de WinSockAPI
1. Función WSAStartup
Para llamar a cualquiera en su aplicación de la función Winsock API, lo primero que debe hacer es completar la inicialización del servicio Winsock a través de la función WSAStartup, por lo que debe llamar a la función WSAStartup.
Declarar Función WSAStartup Lib "ws2_32.dll" _
(ByVal wVersionRequired As Long, lpWSAData As WSAData) As Long
Esta función tiene dos parámetros: wVersionRequired y lpWSAData.
El parámetro wVersionRequired define la versión más alta que Windows Sockets puede proporcionar. Su byte de orden superior define el número de versión menor y el byte de orden inferior define el número de versión principal. Los siguientes dos ejemplos de versiones de Winsock utilizadas en VB:
Inicializar versión 1.1
lngRetVal = WSAStartup(&H101, udtWinsockData)
Inicializar versión 2.2
p>
lngRetVal = WSAStartup(&H202, udtWinsockData)
El segundo parámetro es la estructura de datos de WSADATA, que recibe datos cuando se ejecuta Windows Sockets.
Escriba WSAData
wVersion como número entero
wHighVersion como número entero
szDescription como cadena * WSADESCRIPTION_LEN
szSystemStatus como Cadena * WSASYS_STATUS_LEN
iMaxSockets como entero
iMaxUdpDg como entero
lpVendorInfo como largo
Tipo de fin
Datos Los miembros se describen en la siguiente tabla:
Campo Descripción
wVersión Información de versión de Windows Sockets.
wHighVersion La versión más alta de Winsock compatible obtenida al cargar el archivo de la biblioteca.
Suele ser el mismo que el valor de wVersion.
szDescription Descripción detallada de la ejecución de Windows Sockets
szSystemStatus contiene información de configuración y estado relacionada
iMaxSockets representa el número máximo de sockets abiertos al mismo tiempo, que es 0 Indica que no hay límite.
iMaxUdpDg indica el número máximo de datagramas abiertos al mismo tiempo, 0 indica que no hay límite.
Información especificada por el proveedor de lpVendorInfo reservada
No hay ningún valor de retorno para lpVendorInfo en las versiones 1.1 y 2.2 de Winsock. Debido a que winsock 2 admite múltiples protocolos de transporte, iMaxSockets e iMaxUdpDg solo se pueden usar en winsock 1.1, que solo admite TCP/TP. Para obtener estos valores en Winsock 2, puede utilizar la función WSAEnumProtocols.
La función devuelve 0 si tiene éxito o si se devuelve un código de error.
Significado del código de error
WSASYSNOTREADY indica que la red no está lista para la transmisión.
WSAVERNOTSUPPORTED La implementación actual de WinSock no admite la versión de especificación de Windows Sockets especificada por la aplicación
WSAEINPROGRESS Hay una llamada de bloqueo de WinSock en curso
WSAEPROCLIM El protocolo solicitado no está en la configuración del sistema o no existe ninguna implementación que lo respalde.
WSAEFAULT lpWSAData no es un puntero válido
2.Función WSACleanup
Cada vez que llama a la función WSAStartup, debe llamar a la función WSACleanup para notificar al sistema para desinstalar el archivo de biblioteca y borrar los recursos asignados. Esta función es muy simple y no tiene parámetros:
Declarar función WSACleanup Lib "ws2_32.dll" () As Long
3. Crear función de socket
Declarar función socket Lib "ws2_32.dll" (ByVal af As Long, _
ByVal s_type As Long,
ByVal Protocol As Long) As Long p>
La función tiene tres parámetros para definir qué tipo de socket crear. Los tres parámetros son:
Argumento Descripción Tipo de enumeración
af Especificación de familia de direcciones. . AddressFamily
s_type Especificación de tipo para el nuevo socketType
Protocolo de protocolo que se utilizará con el socket SocketProtocol
que es específico de la dirección indicada
p>familia .
AddressFamily:
AF_UNSPEC = 0 '/* sin especificar */
AF_UNIX = 1 '/* local al host (tuberías , portales) */
AF_INET = 2 '/* interconexión de redes: UDP, TCP, etc. */
AF_IMPLINK = 3 '/* direcciones imp de arpanet */
AF_PUP = 4 '/* protocolos pup: p. ej. BSP */
AF_CHAOS = 5 '/* con protocolos CHAOS */
AF_NS = 6 '/* protocolos XEROX NS */
AF_IPX = AF_NS '/* Protocolos IPX: IPX, SPX, etc. */
AF_ISO = 7 '/* Protocolo ISO
cols */
AF_OSI = AF_ISO '/* OSI es ISO */
AF_ECMA = 8 '/*fabricantes europeos de ordenadores */
AF_DATAKIT = 9' /* protocolos datakit */
AF_CCITT = 10 '/*protocolos CCITT, X.25 etc */
AF_SNA = 11 '/*IBM SNA */
AF_DECnet = 12'/*DECnet*/
AF_DLI = 13'/*Interfaz de enlace de datos directo*/
AF_LAT = 14'/*LAT*/
AF_HYLINK = 15 '/* NSC Hyperchannel */
AF_APPLETALK = 16 '/* AppleTalk */
AF_NETBIOS = 17 '/* Direcciones estilo NetBios */ p>
AF_VOICEVIEW = 18 '/* VoiceView */
AF_FIREFOX = 19 '/* Protocolos de Firefox */
AF_UNKNOWN1 = 20 '/* ¡Alguien está usando esto! */
AF_BAN = 21 '/* Banyan */
AF_ATM = 22 '/* Servicios nativos de cajero automático */
AF_INET6 = 23 '/* Internetwork Versión 6 */
AF_CLUSTER = 24 '/* Microsoft Wolfpack */
AF_12844 = 25 '/* IEEE 1284.4 WG AF */
AF_MAX = 26
Tipos de socket:
SOCK_STREAM = 1 ' /* socket de flujo */
SOCK_DGRAM = 2 ' /* socket de datagrama */
SOCK_RAW = 3 ' /* interfaz de protocolo sin formato */
SOCK_RDM = 4 ' /* mensaje entregado de manera confiable */
SOCK_SEQPACKET = 5 ' /* flujo de paquetes secuenciado */
Protocolos:
>
IPPROTO_IP = 0 '/* ficticio para IP */
IPPROTO_ICMP = 1 '/* protocolo de mensajes de control */
IPPROTO_IGMP = 2 '/* protocolo de gestión de grupos de Internet */
IPPROTO_GGP = 3 '/* puerta de enlace^2 (obsoleto) */
IPPROTO_TCP = 6 '/* tcp */
IPPROTO_PUP = 12 ' /* pup */
IPPROTO_UDP = 17 '/* protocolo de datagrama de usuario */
IPPROTO_IDP = 22 '/* xns idp */
IPPROTO_ND = 77 '/* Protocolo de disco de red NO OFICIAL */
IPPROTO_RAW = 255 '/* paquete IP sin formato */
IPPROTO_MAX = 256
Esta función puede crear un protocolo de red específico El socket de red del protocolo, por ejemplo, para el protocolo UDP, lo puedes escribir así:
s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
s=socket(AF_INET , SOCK_STREAM, IPPROTO_TCP)
4. Cerrar función de socket
Declarar función closesocket Lib "ws2_32.dll" (ByVal s As Long) mientras
La función tiene un parámetro para crear un socket Handle
5. Función de conexión
Declarar función connect Lib "ws2_32.dll" (ByVal s As Long, _
ByRef name As sockaddr_in, _
ByVal namelen As Long) As Long
Parámetros
s El identificador del socket de la conexión.
nombre La dirección para establecer la conexión.
namelen La longitud de la dirección de conexión.
Valor de retorno
Devuelve 0 en caso de éxito. De lo contrario, se devuelven SOCKET_ERROR y el número de error correspondiente Err.LastDllError.
Obviamente al llamar a esta función necesitamos saber el identificador del socket, el número de puerto y el nombre del host (o dirección IP del host) de la computadora a conectar. Sabemos que el método Connect del control Winsock se basa en dos variables: RemoteHost y RemotePort. Este método no requiere un identificador de socket porque ya está encapsulado en un objeto COM. Podría pensar que la función de conexión también debería aceptar la misma configuración de variables, sin embargo, este no es el caso.
La transmisión de la dirección de host y el número de puerto de la función de conexión se basa en la estructura sockaddr_in.
Tipo público sockaddr_in
sin_family Como entero
sin_port Como entero
sin_addr Siempre
sin_zero(1 A 8) Como byte
Tipo final
6. Función auxiliar de socket
Declarar función bind Lib "ws2_32.dll" (ByVal s As Long, _
ByRef name As sockaddr_in, _
ByRef namelen As Long) As Long
s es un socket creado usando la función Socket y el nombre apunta a Un puntero a la estructura que describe el objeto de comunicación, namelen es la longitud de la estructura.
Los componentes de la estructura incluyen:
Dirección IP: correspondiente a nombre.sin_addr.s_addr
Número de puerto: correspondiente a nombre.sin_puerto
Los números de puerto se utilizan para representar diferentes procesos (es decir, aplicaciones) en la misma computadora. Hay dos métodos de asignación:
El primer método de asignación es que el proceso permite que el sistema asigne automáticamente el socket. número de puerto. Simplemente especifique el número de puerto como 0 antes de llamar a bind. Los números de puerto asignados automáticamente por el sistema están entre 1024 y 5000, y cualquier puerto TCP o UDP entre 1 y 1023 está reservado. El sistema no permite que ningún proceso utilice el puerto reservado a menos que su ID de usuario efectivo sea cero (es decir, superusuario). ).
El segundo método de asignación consiste en que el proceso asigne un puerto específico al socket. Esto es útil para servidores que necesitan asignar un puerto conocido al socket. El rango especificado está entre 1024~65536.
Tipo de dirección: corresponde a nombre.sin_familia, generalmente asignado a AF_INET, que significa una dirección de internet (es decir, dirección IP). La dirección IP generalmente se expresa en notación de puntos, pero en realidad es un entero de 32 bits y los dos se pueden convertir mediante la función inet_addr().
7. Función de escucha de socket
Declarar función de escucha Lib "ws2_32.dll" (ByVal s As Long, ByVal backlog As Long) As Long
La escucha La función se utiliza para configurar el Socket en el estado de escucha, lo que indica que el Socket está listo para conectarse. Tenga en cuenta que esta función se usa generalmente en programas de servicio, donde s es el socket creado usando la función Socket y el parámetro backlog se usa para establecer la cantidad de clientes que esperan la conexión.
8. Aceptar solicitud de conexión
Declarar función aceptar Lib "ws2_32.dll" (ByVal s As Long, ByRef addr As sockaddr_in, _
ByRef addrlen As Long) As Long
La aplicación del servidor llama a esta función para aceptar la solicitud de conexión del Socket del cliente. El valor de retorno de la función aceptar () es un nuevo Socket, y el nuevo Socket se puede utilizar para completar el servidor. y client El socket original aún puede aceptar solicitudes de conexión de otros clientes.
9. Recibir información
Declarar función recv Lib "ws2_32.dll" (ByVal s As Long, _
ByRef buf As Any, _
ByVal buflen As Long, _
ByVal flags As Long) As Long
s El identificador de un socket conectado
buf recibido El buffer de datos
longitud del búfer len
flags especifica el identificador desde el cual llamar
El primer parámetro es el identificador del socket, devuelto para el valor de la función del socket. Es decir: necesitamos decirle a la función recv qué socket está accediendo a la función.
El segundo parámetro es: un búfer que puede cargar algunos datos después de ejecutar la función. Pero no tiene que ser lo suficientemente largo para recibir todos los datos en el búfer de Winsock; el tamaño del búfer está limitado a 8192 bytes (8 Kbytes). Por lo tanto, si el tamaño de los datos en el búfer de Winsock es mayor que el búfer de la función recv, debe llamar a esta función varias veces hasta que se obtengan todos los datos.
Si la aplicación define la longitud del buffer, la función recv debe saber cuántos bytes puede contener el buffer. El tercer parámetro es para este propósito.
El último parámetro es opcional y no lo usaremos hoy. Este parámetro tiene dos indicadores de selección: MSG_PEEK y MSG_OOB, que se utilizan para cambiar el comportamiento de la función.
MSG_PEEK toma el número de los datos de entrada. Los datos se copian en el búfer pero no se eliminan de la cola de entrada. La función devuelve el número actual de bytes que se recibirán.
MSG_OOB maneja datos OOB (fuera de banda). Hay dos tipos de paquetes en la red, paquetes normales y paquetes salientes. El ajuste se puede determinar examinando el encabezado de un paquete TCP/IP en busca de un indicador específico.
10. Enviar información
Declarar función enviar Lib "ws2_32.dll" (ByVal s As Long, _
ByRef buf As Any, _
ByVal buflen As Long, _
ByVal flags As Long) As Long
Consulte la información de recepción para conocer los parámetros
Cuatro, servidor y interacción con el cliente
El método más utilizado en la actualidad es: el programa de servicio escucha las solicitudes del servicio en una dirección conocida (incluida la información del puerto). un cliente solicita el servicio. Se realizó una solicitud de conexión a la dirección. En este momento, el programa de servicio se despierta y responde adecuadamente a la solicitud del cliente. Tenga en cuenta que la interacción entre el servidor y el cliente puede estar orientada a la conexión (basada en sockets de flujo) o sin conexión (basada en sockets de datagramas).
Servidor
socket()
|
bind()
|
escuchar() cliente
|
| socket()
| establecer conexión|
aceptar() <--- - ---------------------- connect()
| Solicitar datos|
recv() <--- -------------------------- enviar()
|
Procesar solicitudes de servicio|
| Datos de respuesta|
enviar() ------------------------------ - > recv()
|
close() close()
Cinco, otros
Comparación: control WinSock p >
Ventajas: Fácil de usar, pequeña carga de trabajo.
Desventajas: Pocas funciones, solo admite protocolos TCP y UDP y requiere control WinSock (el sistema se instala por defecto sin el archivo MSWINSCK.OCX)
Apto para principiantes
WinSockAPI
Ventajas: Potente, admite múltiples protocolos, flexible de usar. El wsock32.dll (28K) o ws2_32.dll (69K) llamado por WinSockAPI es una biblioteca de funciones integrada para el. Sistema Windows, para que no tengas que preocuparte por archivos perdidos.
Desventajas: complejo de usar, gran cantidad de programación, requiere cierta base
Adecuado para programas de red con mayores requisitos.