Programación de red 4: un breve análisis de la API proporcionada por Linux (pasos de desarrollo para el servidor y el cliente de Socket)

Un breve análisis de la API proporcionada por Linux (pasos de desarrollo para el servidor y el cliente de Socket)

1. Protocolo de conexión: (TCP / UDP)

//创建套接字
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain,int type,int protocol);
返回sockfd---失败返回-1

dominio:
especifique la familia de protocolos utilizada, normalmenteAF_INET, Representa la familia de protocolos de Internet (familia de protocolos TCP / IP);

AF_INET Dominio de Internet IPV4
AF_INET6 IPV6 dominio de Internet
AF_UNIX dominio unix
AF_ROUTE conector de enrutamiento
AF_KEY conector de llave
AF_UNSPEC no especificado

El parámetro de tipo especifica el tipo de conector:
SOCK_STREAM: El
socket de transmisión proporciona un flujo de comunicación confiable y orientado a la conexión, utiliza el protocolo TCP para garantizar la corrección y secuencia de la transmisión de datos
SOCK_DGRAM: El
socket del datagrama define un servidor sin conexión. Los datos se transmiten a través de mensajes independientes. Es desordenado, no garantiza confiabilidad y está libre de errores. Utiliza el protocolo de datagramas UDP .
SOCK_RAW:
Permitir que el programa use el protocolo subyacente. El socket original se ejecuta para acceder directamente al protocolo subyacente como IP o ICMP. Es poderoso pero inconveniente de usar. Se usa principalmente para el desarrollo de algunos protocolos .


al protocolo
se le suele asignar el valor "0
0 Seleccione el protocolo predeterminado correspondiente al tipo de tipo
== IPPROTO_TCP Protocolo de transmisión TCP ==
IPPROTO_UDP Protocolo de transmisión UDP
IPPROTO_SCTP Protocolo de transmisión SCTP
IPPROTO_TIPC Protocolo de transmisión TIPC

2. Función de asignación de número de IP, número de puerto y palabra de descripción correspondiente: función bind ()

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

La función bind () asigna una dirección específica en una familia de direcciones al socket. Por ejemplo, lo que corresponde a AF_INET y AF_INET6 es asignar una combinación de dirección y número de puerto ipv4 o ipv6 al socket.

Función: se utiliza para vincular la dirección IP y el número de puerto a los
parámetros de socketfd :
sockfd: La palabra de descripción de socket, que es creada por la función socket () e identifica de forma única un socket. La función bind () vinculará un nombre a este descriptor.
addr: Un puntero const struct sockaddr *, que apunta al sockfd que se va a enlazarDirección de protocolo
Addrlen: Corresponde a la longitud de la dirección.

Estructura de direcciones de protocoloVaría según la familia de protocolos de direcciones cuando se crea el socket. Por ejemplo, ipv4 corresponde a:

struct sockaddr_in {
    
    
    sa_family_t    sin_family; //协议族
    in_port_t      sin_port;   //端口号
    struct in_addr sin_addr;   //IP地址结构体
};
struct in_addr {
    
    
    uint32_t       s_addr;     /* address in network byte order */
};

Por lo general, el servidor enlazará una dirección conocida == (como la dirección IP + número de puerto) == cuando se inicia el servidor, que se utiliza para proporcionar servicios, y el cliente puede conectarse al servidor a través de él; no es necesario especificar el cliente y el sistema automáticamente Asigne un número de puerto y su propia combinación de dirección IP. Esta es la razón por la que generalmente el servidor llamará a bind () antes de escuchar, pero el cliente no lo llamará, sino que el sistema genera uno aleatoriamente cuando se conecta ().

3.Escucha () función de monitoreo, conecta () función de conexión

Si como servidor, después de llamar a socket () y bind (), se llamará a listen () para monitorear el socket. Si el cliente llama a connect () para enviar una solicitud de conexión en este momento, el servidor recibirá la solicitud.

#include <sys/types.h> 
#include <sys/socket.h>
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

El primer parámetro de la función de escucha es el que se va a monitorearpalabra de descripción de enchufe, El segundo parámetro es la cola que el socket correspondiente puede poner en colaNúmero máximo de conexiones. El socket creado por la función socket () es de tipo activo por defecto, y la función listen convierte el socket en un tipo pasivo y espera la solicitud de conexión del cliente.

El primer parámetro de la función de conexión esLa descripción del socket del cliente., El segundo parámetro esLa dirección de socket del servidor, El tercer parámetro es la dirección del socketlongitud. El cliente establece una conexión con el servidor TCP llamando a la función de conexión.
  
4.accept () función de solicitud de recepción

Después de que el servidor TCP llame a socket (), bind () y listen () a su vez, escuchará la dirección de socket especificada. Después de que el cliente TCP llama a socket () y connect () a su vez, envía una solicitud de conexión al servidor TCP. Después de que el servidor TCP escuche la solicitud, llamará a la función accept () para recibir la solicitud, de modo que se establezca la conexión. Después de eso, puede iniciar operaciones de E / S de red, es decir, leer y escribir operaciones de E / S similares a archivos normales.

#include <sys/types.h> 
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //返回连接connect_fd

Los tres parámetros de la función son:

sockfd: es el socket de escucha explicado anteriormente. Este socket se usa para monitorear un puerto. Cuando un cliente se conecta al servidor, usa este número de puerto, y este número de puerto está actualmente conectado a este socket Asociado. Por supuesto, el cliente no conoce los detalles del socket, solo conoce una dirección y un número de puerto.
addr: este es un parámetro de resultado, que se utiliza para recibir un valor de retorno. Este valor de retorno especifica la dirección del cliente. Por supuesto, esta dirección se describe mediante una estructura de dirección determinada. El usuario debe saber qué tipo de estructura de dirección es esta. Si no está interesado en la dirección del cliente, puede establecer este valor en NULL.
len: Como todos piensan, también es el parámetro del resultado, se utiliza para aceptar el tamaño de la estructura de direcciones anterior, indica el número de bytes que ocupa la estructura de direcciones. Del mismo modo, también se puede establecer en NULL.

Si accept devuelve exitosamente, el servidor y el cliente han establecido correctamente una conexión, y el servidor completa la comunicación con el cliente a través del socket devuelto por accept.

Nota:
Accept bloqueará el proceso de forma predeterminada hasta que se establezca una conexión de cliente y regrese. Devuelve un socket recién disponible, que es un socket de conexión.

En este punto necesitamos distinguir entre dos tipos de sockets:

Toma de escucha: El conector de escucha es como el parámetro de aceptación sockfd. Es el conector de escucha. Después de llamar a la función de escucha, el servidor comienza a llamar a la función socket (). Se llama descriptor de conector de escucha (conector de monitoreo)
Conecte el enchufe: Un enchufe cambiará de un enchufe conectado activamente a un enchufe de escucha; y la función de aceptación devuelve la descripción del enchufe conectado (un enchufe conectado), que representa el punto donde ya existe una red conexión.

Un servidor generalmente solo crea un descriptor de socket de escucha, que siempre existe durante el ciclo de vida del servidor. El kernel crea un descriptor de socket conectado para cada conexión de cliente aceptada por el proceso del servidor.Cuando el servidor completa el servicio para un cliente determinado, se cierra el descriptor de socket conectado correspondiente.

El socket de conexión socketfd_new no ocupa un nuevo puerto para comunicarse con el cliente y aún usa el mismo número de puerto que el socket de escucha socketfd.
  
5.read (), write () y otras funciones

Existen los siguientes grupos de operaciones de E / S de red:

read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()

6.función de cierre

int close(int fd);

El comportamiento predeterminado de cerrar un socket TCP es marcar el socket como cerrado y luego regresar inmediatamente al proceso de llamada. El proceso de llamada ya no puede utilizar la palabra de descripción, lo que significa que ya no se puede utilizar como primer parámetro de lectura o escritura.

Nota: La operación de cierre solo realiza el recuento de referencias de la correspondiente palabra de descripción de socket -1, y solo cuando el recuento de referencias sea 0, activará al cliente TCP para enviar una solicitud de terminación de conexión al servidor.

7. API de traducción de direcciones:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
//把字符串形成的“192.168.1.123”转为网络能识别的格式
char *inet_ntoa(struct in_addr in);
//把网络格式的ip地址转化为字符串形式

8. API de conversión de Endian:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);//返回网络字节序的值
uint16_t htons(uint16_t hostshort);//返回网络字节序的值
uint32_t ntohl(uint32_t netlong);//返回主机字节序的值uint32_t
uint16_t ntohs(uint16_t netshort);//返回主机字节序的值

h representa el host, n representa la red, s representa corto (dos bytes) y l representa largo (4 bytes); la conversión entre el orden de bytes del host y el orden de bytes de la red se puede realizar mediante las cuatro funciones anteriores. A veces se puede usarINADDR_ANY, INADDR_ANY especifica la dirección que debe obtener el sistema operativo.

La escritura de código entre el cliente y el servidor se puede completar a través de la API anterior.

Consulte la siguiente sección para la implementación del código.Programación de red 5explique

Supongo que te gusta

Origin blog.csdn.net/weixin_40734514/article/details/108555217
Recomendado
Clasificación