Programación de red Linux | programación de red avanzada

Programación avanzada en red

Hay principalmente 4 modelos IO en Linux

  • Bloqueo de E / S: el más utilizado, de forma predeterminada, el conector está en modo de bloqueo de E / S una vez establecido
  • E / S sin bloqueo: puede evitar que el proceso se bloquee en las operaciones de E / S, se requiere sondeo
  • E / S impulsada por señales: un modelo de comunicación asíncrona
  • Multiplexación de E / S: permite controlar múltiples E / S al mismo tiempo

En aplicaciones prácticas, suele darse el caso de que varios clientes se conecten al servidor. Si se usa una función de bloqueo, si el recurso no está listo, el proceso que llama a la función entrará en suspensión, de modo que no pueda manejar otras solicitudes. Esta sección ofrece tres métodos para resolver la multiplexación de E / S, a saber, el procesamiento asíncrono y sin bloqueo (usando la función fcntl ()) y el procesamiento multiplexado (usando la función select () o la función poll ()) . Además, existen multiprocesos y multiprocesos, que son métodos de procesamiento de transacciones comúnmente utilizados en la programación de redes.

1. Sin bloqueo

Cuando configuramos un socket en modo sin bloqueo, es equivalente a decirle al kernel: "Cuando la operación IO que solicité no se puede completar de inmediato y desea que mi proceso se suspenda y espere, no lo haga, regrese inmediatamente. Dame el error ". Cuando una aplicación usa un socket en modo sin bloqueo, necesita usar un bucle para probar continuamente si un descriptor de archivo tiene datos para leer (llamado sondeo)

  • Use la función fcntl (int fd, int cmd, int arg) para establecer el modo sin bloqueo
  • cmd está establecido en F_SETFL
  • arg se establece en O_NONBLOCK
/*****设置非阻塞IO模式*****/
int flag = fcntl(sockfd, F_GETFL);	//cmd为F_GETFL即返回fd指向的文件的状态
flag |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flag);

2. E / S asíncrona

El uso de mecanismos de bloqueo, no bloqueo y multiplexación puede llevar a cabo la comunicación de red de manera eficaz, pero el método más eficaz es utilizar el mecanismo de notificación asíncrono, que es el más común en la programación de E / S de dispositivos. El kernel envía una señal SIGIO a un determinado proceso mediante el uso de E / S asíncrona cuando llega el momento en que debe procesarse. De esta manera, la aplicación no necesita esperar constantemente a que ocurran ciertos eventos, sino que puede agotarse para completar otras tareas. Solo cuando recibe la señal SIGIO del kernel, puede manejarla.

  • Utilice la función fcntl (int fd, int cmd, int arg) para configurar el modo IO asíncrono
  • Utilice el comando F_SETOWN de la función fcntl () para hacer que el socket pertenezca al proceso actual
  • Utilice el comando F_SETFL de la función fcntl () para establecer arg en O_ASYNC
/*****设置异步IO模式*****/
fcntl(sockfd, F_SETOWN, getpid());	//将套接字归属于该进程,使内核判断应该向哪个进程发送信号
int flag = fcntl(sockfd, F_GETFL);	//cmd为F_GETFL即返回fd指向的文件的状态
flag |= O_ASYNC;
fcntl(sockfd, F_SETFL, flag);

3. Multiplexación de E / S

La aplicación procesa múltiples flujos de entrada y salida al mismo tiempo. Si se usa el modo de bloqueo, no se logrará el propósito esperado; si se usa el modo sin bloqueo, el sondeo de múltiples entradas desperdiciará tiempo de CPU; si se configuran varios procesos para procesar por separado Un enlace de datos, sincronización y comunicación entre nuevos procesos complicará el programa; una mejor forma es usar multiplexación IO, la idea básica es:

  • Primero construya una tabla de descriptores relacionados y luego llame a una función. La función regresa cuando uno o más de estos descriptores de archivo están listos para E / S
  • Cuando la función regrese, dígale al proceso qué descriptor está listo para operaciones de E / S

Utilice las funciones select () / poll () para lograr la multiplexación:

/*****select()函数*****/
函数原型:int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
传 入 值:maxfd 所有文件描述符的最大值加1
		 readfds 所有要读的文件的文件描述符的集合
		 writefds 所有要写的文件的文件描述符的集合
		 exceptfds 其他要向我们通知的文件描述符
		 timeout 超时设置 -->NULL:一直阻塞,直到有文件描述符就绪或出错
		 				 -->0:仅仅检测文件描述符集的状态,然后立即返回
		 				 -->不为0:在指定时间内,如果没有事件发生,则超时返回

Cuando se llama a la función select (), el proceso se bloqueará hasta que haya un archivo para leer, un archivo para escribir o el tiempo de espera expire. Para configurar el descriptor de archivo es necesario utilizar varias macros:

#include <sys/select.h>
int FD_ZERO(fd_set *fdset);			//从fdset中清除所有的文件描述符
int FD_CLR(int fd,fd_set *fdset);	//将fd从fdset中清除
int FD_SET(int fd,fd_set *fdset);	//将fd加入到fdset
int FD_ISSET(int fd,fd_set *fdset);	//判断fd是否在fdset集合中
/*例如*/
fd_set rset;
int fd;
FD_ZERO(&rset);
FD_SET(fd,&rset);
FD_SET(stdin&rset);
//在select返回之后,可以使用FD_ISSET(fd,&rset)测试给定的位置是否置位。
if(FD_ISSET(fd,&rset))
{
    
    ......}

La siguiente figura muestra el modelo de multiplexación TCP
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/Chuangke_Andy/article/details/108437802
Recomendado
Clasificación