Red de conocimiento informático - Conocimiento del nombre de dominio - Cómo aprender a programar la red de Windows

Cómo aprender a programar la red de Windows

Aprendizaje imprescindible para principiantes: una introducción clásica a la programación de redes de Windows

Autor: huyoo

Para un principiante en la programación de redes de Windows, el siguiente método es una Introducción clásica.

Se recomienda a los principiantes que no utilicen las clases proporcionadas por MFC, sino que utilicen la API de Windows para crear un servidor y un cliente simples. Esto les ayudará a comprender el mecanismo de programación del socket.

Para simplificar, la aplicación se basa en los cuadros de diálogo estándar de MFC.

Winsock se implementa utilizando la API de WINDOWS:

(1) Hay dos subprocesos en el lado del servidor:

Subproceso principal: debe escribir la siguiente función para implementarlo

#define NETWORK_EVENT USER_MESSAGE 100 file://Definir eventos de red

sockaddr_in clientaddr file://Almacenar temporalmente la dirección IP del cliente

archivo ://Defina su propia función de mapeo de mensajes, asigna el evento de red definido anteriormente a la función de procesamiento

file://OnNetEvent es la función de procesamiento de eventos de red, que se define a continuación

ON_MESSAGE(NETWORK_EVENT, OnNetEvent);

Llame a la siguiente subfunción para inicializar la red en la función de inicialización en su cuadro de diálogo

Archivo BOOL InitNetwork(): //Inicializar la red

{

p>

archivo: //Inicializar protocolo TCP

BOOL ret = WSAStartup(MAKEWORD(2, 2), & wsaData);

if(ret != 0)

{

MessageBox("¡Error al inicializar el socket!");

return FALSE;

}

archivo://Crear socket del lado del servidor

SOCKET serverSocket

= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if(serverSocket == INVALID_SOCKET)

{

MessageBox("¡Error al crear el socket!");

closesocket(m_Socket);

WSACleanup( );

devuelve FALSO

}

archivo: //Enlazar a un puerto local

sockaddr_in localaddr;

p>

localaddr.sin_family = AF_INET;

localaddr.sin_port = htons(1688); sin_addr.s_addr = 0;

if (bind(serverSocket, (const struct sockaddr*)&localaddr,

sizeof(sockaddr)) == SOCKET_ERROR)

{

MessageBox("¡Error en la determinación de la dirección de enlace!");

closesocket(m_Socket);

WSACleanup(); FALSE;

}

p>

archivo: //Registra eventos asincrónicos de red, m_hWnd es el identificador del cuadro de diálogo principal o ventana principal de la aplicación

WSAAsyncSelect(serverSocket, m_hWnd, NETWORK_EVENT,

FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE

p>

listen(serverSocket, 5); file://Establecer modo de escucha

return TRUE

}

file: //Definición de red; función de respuesta al evento

void OnNetEvent(WPARAM wParam, LPARAM lParam)

{

file: //Llame a la función API para obtener el tipo de evento de red

{ p>

int iEvent = WSAGETSELECTEVENT(lParam);

file: //Obtiene el socket del cliente que emitió este evento

SOCKET pSock = (SOCKET )wParam;

switch(iEvent)

{

caso FD_ACCEPT: archivo://solicitud de conexión del cliente

{

OnAccept();

romper;

}

caso FD_CLOSE: archivo://Evento de desconexión del cliente:

{

OnClose(pSock);

break;

}

case FD_READ: file://Evento de llegada de paquete de red

p>

{

OnReceive(pSock);

romper

}

caso FD_WRITE: file://enviar eventos de datos de red

{

OnSend(pSock

break

}

<; p>predeterminado: break

}

}

void OnAccept(SOCET pSock) file: //Respuesta a la función de solicitud de conexión del cliente

{

int len ​​​​= sizeof(sockaddr);

file: //Llama a la función API, acepta la conexión y devuelve un nuevo socket

file: //También se puede obtener la dirección IP del cliente

SOCKET clientSocket = Accept(serverSocket,

(struct sockaddr*)amp; clientaddr, amp;len); /p>

archivo: //Registra eventos asincrónicos para el nuevo socket, tenga en cuenta que no hay ningún evento de aceptación

if(WSAAsyncSelect(clientSocket, m_hWnd, IP_EVENT,

FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)

p>

{

MessageBox("¡Error al registrar el evento asincrónico!");

 }

archivo: //Escribe tu propia función para guardar la información relevante de este cliente: socket,

//dirección IP, hora de inicio de sesión

saveClientSocket(clientSocket, clientAddr, currentTimer);

}

void OnClose(SOCET pSock)

<

p>{

file: //Función autoescrita, finaliza la comunicación con el cliente correspondiente, libera los recursos correspondientes y realiza el procesamiento correspondiente

endClientSocket(pSock

}

void OnSend(SOCET pSock)

{

file: //Función autoescrita para realizar algún preprocesamiento al enviar datos al cliente

handleOnSend(pSock);

}

void OnReceive(SOCET pSock)

{

recv (...); archivo: //Llame a la función API para leer el paquete de datos en el búfer de la red

archivo: //Función autoescrita para conectar este paquete de datos al cliente que envió estos datos

p>

archivo: //clientSocket se encapsula en un mensaje de red

buildNetMsg(...

archivo: //Self-); función escrita para colocar este mensaje de red en una cola de mensajes, es procesado por el hilo de trabajo

saveNetMsg(...);

SetEvent(...); // Activa el hilo de trabajo con el objeto de evento

p>

}

Después de que el cliente inicia sesión, envía inmediatamente el nombre de su computadora al servidor. lo guarda. De esta manera, el servidor puede mostrar toda la información del cliente en línea, incluido: nombre de la computadora del cliente, dirección IP, hora de inicio de sesión, etc.

Nota: El cliente no tiene la función OnAccept(), pero sí la función OnConnect().

Subproceso de trabajo:

Crea e inicia un subproceso de trabajo cuando se inicializa tu aplicación

AfxBeginThread(WorkThread, this, THREAD_PRIORITY_NORMAL

); file://este puede ser el identificador del cuadro de diálogo principal o de la ventana principal de la aplicación

UINT WorkThread(LPVOID pParam)

{

while(1)

{

file: //Esperar a que lleguen múltiples eventos

int ret = WaitForMultipleObject(...);

switch; (ret)

{

case OBJECT_0:

{

if(bNewNetMsg) file://Ver cola de mensajes de red ¿Existe? ¿Un nuevo mensaje de red?

{

readNetMsg(...); file: //Si hay un nuevo mensaje de red, léelo en voz alta

handleNetMsg. (...); file://procesar este mensaje de red

}

break;

}

case OBJECT_0 1:

{

archivo: //Salir del procesamiento

break;

}

predeterminado: break;

}

return 0;

}

El cliente es de un solo subproceso. Al iniciar sesión en el servidor, utilice la conexión. función () para enviar una solicitud de conexión;

El cliente no tiene la función OnAccept(), pero tiene la función OnConnect().

Realizar preprocesamiento al enviar solicitudes de conexión en la función OnConnect()

Responder y procesar datos de red en la función OnReceive()

En OnClose (); función para responder al evento de apagado del servidor

Realice un preprocesamiento al enviar datos en la función OnSend()

Si también desea lograr la comunicación en línea entre clientes Para la comunicación (así; -llamada sala de chat), también puede crear un conjunto de modelos de multidifusión LAN multipunto a multipunto basado en el protocolo UDP en el cliente. Cuando charle con usted más tarde, primero puede implementar el programa anterior.

El modelo asincrónico de E/S anterior se basa en el mecanismo de mensajes de Windows. Además, también se puede utilizar el modelo de evento, el modelo de superposición o el modelo de puerto de finalización. que consulte la Guía de programación de redes de Windows y libros similares.

Si domina el mecanismo anterior, debe tener cierta comprensión del mecanismo Winsock para programar programas de red. A continuación, podrá realizar una programación más interesante, que no solo puede transmitir datos ordinarios en Internet. , pero también puede transmitir datos de voz y video. También puede crear una sala de chat usted mismo y compartir sus resultados con sus compañeros de clase en la LAN del laboratorio.