Wirehark agarra el protocolo de enlace de tres vías del tcp y cuatro paquetes ondulados

Wirehark agarra el protocolo de enlace de tres vías del tcp y cuatro paquetes ondulados

En primer lugar, todo el mundo necesita conectarse. El proceso de establecimiento de la conexión tcp es lo que necesitamos entender. Sólo después de la comprensión podemos transmitir datos.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Todo el mundo tiene que participar en el proceso de limpieza. El blog anterior a mí hablaba específicamente sobre cómo crearlo, y aquí solo hablo de la captura de paquetes. Enlace: https://blog.csdn.net/qq_45125250/article/details/108549338

Proceso de captura
  • Abre el servidor
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
       #include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
 #include <sys/types.h> 
 #include <sys/socket.h>
void handle_sigchld2(int signo)
{
	int mypid;
	while (( mypid = waitpid(-1, NULL, WNOHANG)) > 0){
		 printf("child %d terminated\n", mypid); 
	} 
}

int main(){

	int			listen_fd,client_fd;
	struct sockaddr_in	serv_addr;
	struct sockaddr_in	cli_addr;
	socklen_t		socklen = sizeof(cli_addr);
	char			buf[1024];
	int 			rv;
	listen_fd = socket(AF_INET, SOCK_STREAM,0);
	if(listen_fd < 0){
		printf("creat socket_fd is failed:[%s]\n",strerror(errno));
		return -1;
	}

	printf("create socket successful\n");
	//将socket_in结构体清空为0
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(8899);
	serv_addr.sin_addr.s_addr = htonl( INADDR_ANY);
	if( bind(listen_fd, (struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){
		printf("bind is failed:[%s]\n",strerror(errno));
		return -1;
	}
	printf("socket:[%d],bind on port:[%d]\n",listen_fd,8899);

	listen(listen_fd,14);
	signal(SIGCHLD, handle_sigchld2);
	while(1){
		client_fd = accept(listen_fd, (struct sockaddr *) &cli_addr, &socklen);
		if(client_fd < 0)       {  
		
  			printf("Accept new client failure: %s\n", strerror(errno));
			continue;               
	       	}
		printf("Accept new client[%s:%d] successfully\n" ,inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
		pid_t		pid;
		int 		status = -1;
		pid = fork();
		if( pid < 0 )
		{
		 printf("fork() create child process failure: %s\n", strerror(errno)); 
		 close(client_fd);
		 continue; 
		}
		else if( pid > 0 )
		{
			/* Parent process close client fd and goes to  accept new socket client again */ 
			waitpid(pid, &status, WNOHANG);
			close(client_fd);
			continue; 
		
		}
		else{
			char                 buf[1024];
			/* Child process close the listen socket fd */
			close(listen_fd);
			printf("Child process start to commuicate with socket client...\n");
			memset(buf, 0, sizeof(buf));
			rv=read(client_fd, buf, sizeof(buf));
			if( rv < 0 ) 
			{
			
				printf("Read data from client sockfd[%d] failure: %s\n", client_fd, strerror(errno)); 
				close(client_fd);
				exit(0);
			}
			printf("Read %d bytes data from Server: %s\n", rv, buf);
			rv = write(client_fd,buf,sizeof(buf));
			if(rv<0){
				printf("write is failed:[%s]\n",strerror(errno));
				close(client_fd);
				exit(0);
			}
			close(client_fd);
			exit(0);
		}

	}
	close(listen_fd);
}

El código anterior es un servidor multiproceso escrito por mi propio servidor, que puede aceptar múltiples clientes, es decir, el lado del servidor creado por él, puerto: 8899,
y luego realizar las siguientes operaciones

gcc  mul_fork.c -o mm
./mm

En este momento, verá esta información impresa
Inserte la descripción de la imagen aquí

  • Abra el cliente
  • El segundo paso es abrir el cliente.La herramienta tcp que usé en el cliente
    Inserte la descripción de la imagen aquí
    ingresa la ip y el puerto del servidor y hace clic en el enlace.Este proceso ya ha establecido un protocolo de enlace tcp de tres vías. El servidor imprimirá la siguiente información.
    Inserte la descripción de la imagen aquí
    En este momento, todo el mundo sabe cómo establecer la comunicación tcp y podemos usar wirehark para capturar paquetes.
  • wirehark
    romper wirehark
    Inserte la descripción de la imagen aquí

Haga clic en la red a la que está conectado, el cable de red que conecté directamente y soy un Ethernet 3. Después de hacer clic, la pantalla es sí.
Inserte la descripción de la imagen aquí

En este momento estamos a punto de comenzar a capturar paquetes, primero configura el filtrado de información, es decir, solo captura los paquetes tcp de la ip y puerto de tu propio servidor.
Inserte la descripción de la imagen aquí

Después de configurar, encendemos el servidor y dejamos que comience a escuchar.
Inserte la descripción de la imagen aquí
Empiece a escuchar, usamos tcptool para conectarnos a nuestro servidor.
Inserte la descripción de la imagen aquí

Estos son los tres paquetes tcp que aparecieron después de hacer clic en Conectar. El primer [SYN] es un paquete de conexión de solicitud, syn = 1, ack = 0. El segundo [SYN, ACK] es el paquete de respuesta del servidor, syn = 1 , ack = 1, el tercero es el paquete de respuesta [ACK] que el cliente enviará al servidor, syn = 0, ack = 1, en este momento nuestra conexión ha sido establecida.

Ahora hablaré sobre el contenido del paquete tcp. Puede ver la imagen que publiqué en la parte superior, que es la información contenida en tcp, y también podemos verla cuando capturamos el paquete.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Primero, explique un paquete de solicitud de conexión [SYN]

Inserte la descripción de la imagen aquí
Al hacer clic en la primera línea, veremos que aparece la siguiente información:
Inserte la descripción de la imagen aquí
El contenido de las dos representaciones es el mismo, pero los métodos de representación son diferentes.
Inserte la descripción de la imagen aquí
Solo mire la parte azul. Esta parte es el contenido del paquete tcp. Lo anterior es el contenido del encabezado de red y el encabezado del enlace de datos. No nos importa aquí, solo la parte tcp.
Comparemos el contenido de las siguientes dos imágenes, la relación correspondiente es exactamente la misma.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
adentro

源端口:fe 1e
目的端口: 22 c3
序号(seq):12 12 fb 2a  
确认号(ack):00 00 00 00
数据偏移: 80
窗口:fa f0 
校验和: 27 5b
紧急指针:00 00
可选项:就是后面的所有字节。12个字节。

Lo único de lo que no hablé arriba son las banderas: bit de bandera, lo mostraré por separado,
Inserte la descripción de la imagen aquí
podemos ver lo que hay dentro,

保留位: 0
urgent : 0
ack : 0
push: 0
reset :0
syn : 0
fin : 0

Debido a que este es el primer paquete, syn: 1, ack: 0. Esto representa la solicitud de conexión, a continuación, hablaré sobre el segundo paquete, que el servidor envía al cliente.

El segundo paquete [SYN, ACK]

Inserte la descripción de la imagen aquí
Como puede ver, syn = 1, ack = 1. Estamos viendo el segundo apretón de manos, es ack igual al primer paquete [SYN] request packet + 1. Lo
Inserte la descripción de la imagen aquí
anterior seq = 12 12 fb 2a Nuestro servidor devuelve El paquete de confirmación es 12 12 fb 2b, que se suma por 1, por lo que es correcto.
La secuencia enviada por segunda vez es: bf 93 84 8c.
Entonces veamos si el paquete ACK devuelto por tercera vez es bf 93 84 8d
Inserte la descripción de la imagen aquí
. Este es el caso. Por lo tanto, nuestra suposición está verificada.

Nota: El apretón de manos de tres vías se produce después de escuchar y antes de aceptar.

Supongo que te gusta

Origin blog.csdn.net/qq_45125250/article/details/115082110
Recomendado
Clasificación