[comunicación de socket] Python realiza una comunicación de socket simple | servidor y cliente

Sugerencia: después de escribir el artículo, la tabla de contenido se puede generar automáticamente. Cómo generarla puede consultar el documento de ayuda a la derecha


prefacio

Contenido de referencia:
1) Introducción a la programación de sockets de comunicación de red TCP/IP

1. Conocimientos básicos de comunicación por socket

1.1 Conocimientos básicos

El zócalo también se conoce como zócalo. La información básica necesaria para el inicio del socket: el número de host y el número de puerto
para la comunicación . (El número de puerto en realidad representa el proceso, es decir, qué programa de aplicación en el host se comunicará) El zócalo está conectado entre dos computadoras como una línea de datos, sirviendo como un puente de comunicación.

1.2 tipo de enchufe

El socket generalmente tiene dos tipos: TCP y UDP .
TCP: Protocolo de control de transmisión Protocolo de control de transmisión
El protocolo TCP es confiable y la otra parte recibirá los datos enviados. TCP es un protocolo basado en flujo de datos (flujo de datos)
UDP: Protocolo de datagramas de usuario El Protocolo de datagramas de usuario
UDP no es confiable y no garantiza necesariamente que la otra parte reciba los datos. UDP generalmente tiene una latencia más baja y consume menos recursos (adecuado para llamadas de voz)

El siguiente contenido se basa en los puntos de conocimiento de TCP y UDP capturados por chatGPT :

TCP y UDP son dos protocolos de transporte de red diferentes. TCP (Protocolo de control de transmisión) es un protocolo orientado a la conexión que establece una conexión confiable y luego envía datos a través de la conexión. UDP (Protocolo de datagramas de usuario) es un protocolo sin conexión que no garantiza una transmisión fiable de datos. El protocolo TCP requiere un apretón de manos de tres vías antes de transmitir datos.Después de que se establece la conexión, la confiabilidad de la transmisión de datos es alta, pero la eficiencia de transmisión es baja. El protocolo UDP no necesita establecer una conexión y la eficiencia de transmisión es alta, pero no se puede garantizar la confiabilidad de los datos.
El protocolo TCP es adecuado para escenarios que requieren una transmisión de datos confiable, como correo electrónico, transferencia de archivos, navegación web, etc. El protocolo UDP es adecuado para escenarios que requieren una transmisión rápida, como la transmisión de audio y video.

Dos, implementación de socket python

2.1 Código de servidor server.py

import socket

# 创建socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 获取本地主机名和端口号
host = socket.gethostname()
port = 8888

# 将socket对象绑定到指定的主机和端口上
server_socket.bind((host, port))

# 开始监听连接
server_socket.listen(1)

# 等待客户端连接
print("等待客户端连接...")
client_socket, client_address = server_socket.accept()

print("连接来自: ", client_address)

# 接收客户端发送的数据
data = client_socket.recv(1024)

# 处理接收到的数据
print("接收到的数据为: ", data.decode())

# 发送响应数据给客户端
message = "欢迎连接到服务器!"
client_socket.send(message.encode())

# 关闭客户端连接
client_socket.close()

1) socket.gethostname() y socket.gethostbyname() son diferentes:
socket.gethostname() obtiene el nombre de host del host actual para usarlo en la conexión Socket. Si desea usar una dirección IP en lugar de un nombre de host para una conexión Socket, puede usar la función socket.gethostbyname() para obtener la dirección IP del host.
2) Con respecto al número de puerto
Una vez que un objeto de socket está vinculado a una dirección IP y un número de puerto a través del método socket.bind(), al objeto de socket se le asignará un número de puerto único. Este número de puerto se puede utilizar para enviar y recibir datos, a fin de realizar la comunicación Socket.
Cuando un cliente quiere conectarse a este servidor, el cliente necesita saber la dirección IP y el número de puerto del servidor. El cliente establece una conexión Socket a través de este número de puerto y se comunica con el servidor para realizar la transmisión e intercambio de datos. Por lo tanto, el número de puerto es un concepto muy importante en la comunicación Socket.
Este número de puerto es para este objeto de socket.
3) server_socket.accept()
server_socket.accept() bloqueará el programa hasta que se conecte un cliente. Una vez que un cliente se conecta, el método accept() devolverá un nuevo objeto de socket client_socket y la información de la dirección del cliente client_address.
El cliente puede comunicarse con el cliente a través de client_socket, y client_address contiene la dirección IP y el número de puerto del cliente, que se pueden usar para identificar la identidad del cliente.

2.2 Código de cliente cliente.py

import socket

# 创建socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 获取服务器的主机名和端口号
host = socket.gethostname()
port = 8888

# 连接到服务器
client_socket.connect((host, port))

# 发送消息给服务器
message = "Hello, 服务器!"
client_socket.send(message.encode())

# 接收服务器发送的响应数据
data = client_socket.recv(1024)

# 处理接收到的响应数据
print("接收到的数据为: ", data.decode())

# 关闭客户端连接
client_socket.close()

1) La diferencia con el código del servidor:
en comparación con el código del servidor, la principal diferencia del código del cliente es que utiliza el método socket.connect() para conectarse al servidor y utiliza el método socket.send() para enviar mensajes al servidor, mientras que el código del servidor usa el método socket.bind() para vincular una dirección IP y un número de puerto, y usa el método socket.listen() para escuchar las solicitudes de conexión del cliente, y luego usa el método socket.accept( ) para aceptar la conexión del cliente, y usa el socket.El método recv() recibe los mensajes enviados por el cliente.
2) message.encode()
message.encode() es un método de cadenas en Python, que se utiliza para codificar cadenas en secuencias de bytes. En Python, las cadenas se almacenan en codificación Unicode, y las secuencias de bytes a menudo se usan para transmitir datos en la transmisión de red, por lo que las cadenas deben codificarse en secuencias de bytes antes de que puedan transmitirse en la red.
El método message.encode() codifica el mensaje de cadena en una secuencia de bytes según el método de codificación predeterminado (generalmente codificación UTF-8) y devuelve un objeto de tipo bytes. Este objeto de bytes puede transmitirse directamente al método send() del socket y enviarse a la red. En el extremo receptor, la secuencia de bytes recibida debe decodificarse en una cadena utilizando el método de decodificación correspondiente ( como el método bytes.decode(), que apareció en el programa del servidor ).

2.3 Cómo correr

Cómo usar: use dos comandos de terminal para ejecutar dos archivos py (servidor primero y luego cliente), y los resultados finales son los siguientes:
servidor:
inserte la descripción de la imagen aquí

cliente:
inserte la descripción de la imagen aquí

El código anterior definitivamente causará muchos problemas para los principiantes
1) ¿Cuál debe ser el número de puerto del cliente?
En la comunicación por socket, el número de puerto se utiliza para identificar el programa del servidor o el programa del cliente. En el programa servidor, necesitamos especificar un número de puerto para que el programa cliente pueda conectarse al puerto para la comunicación. Por lo general, podemos elegir algunos números de puerto predefinidos, por ejemplo, el número de puerto del protocolo HTTP es 80, el número de puerto del protocolo SMTP es 25, etc. Sin embargo, también podemos optar por personalizar el número de puerto si el número de puerto predefinido ya está en uso o no es adecuado para nuestra aplicación.
En el código que proporcionó, el número de puerto es personalizado y se puede configurar como se desee. Generalmente, podemos elegir algunos números de puerto desocupados, como 8888.
2) En consecuencia, ¿el número de puerto del cliente también debe establecerse en el mismo valor?

Si el número de puerto del servidor se establece en 8888, el cliente también debe especificar el número de puerto como 8888 al conectarse al servidor. De esta forma, el cliente puede conectarse al puerto correcto y comunicarse con el servidor. En la comunicación de socket, el número de puerto se usa para identificar el programa del servidor o el programa del cliente, por lo que cuando se comunica entre el cliente y el servidor, el número de puerto debe ser consistente para establecer una conexión con éxito.

Conocimientos complementarios de planificación de redes

Parte de la respuesta proviene de chatgpt
1) Dirección especial: 127.0.0.1

127.0.0.1 es una dirección IP especial, también conocida como dirección de loopback local . Apunta a la interfaz de red de la máquina, es decir, cuando accede a esta dirección, en realidad está accediendo a la propia máquina. Esta dirección se utiliza normalmente para probar aplicaciones de red y, al instalar algún software de servidor en esta máquina, puede utilizar esta dirección para realizar pruebas. Por ejemplo, cuando haya instalado un servidor web en esta máquina, puede usar un navegador para visitar 127.0.0.1 para probar si el servidor web funciona normalmente.
2)
Host = socket.gethostbyname(socket.gethostname()) y host="127.0.0.1" significan lo mismo?
host = socket.gethostbyname(socket.gethostname()) y host="127.0.0.1" no son exactamente lo mismo, aunque ambos pueden usarse para especificar la dirección IP de la máquina.
socket.gethostbyname(socket.gethostname()) devolverá la dirección IP del host actual, que puede ser una dirección IP de red de área local o una dirección IP de red pública. Si su computadora está conectada a una LAN, esta dirección IP se puede usar para comunicarse dentro de la LAN.
host="127.0.0.1" significa utilizar la dirección de bucle invertido local (dirección de bucle invertido), que es 127.0.0.1. Esta dirección es una dirección IP especial, que solo se puede usar dentro de la máquina y no se puede usar para la comunicación en la red de área local o la red pública.
En el código anterior, use socket.gethostbyname(socket.gethostname()) para obtener la dirección IP de la máquina, para que pueda comunicarse en la LAN. Si solo se comunica dentro de la máquina, también puede usar host="127.0.0.1".

3) La diferencia entre la comunicación entre procesos y la comunicación por socket La
comunicación entre procesos y la comunicación por socket son dos métodos de comunicación diferentes, y sus mecanismos de implementación y escenarios de aplicación son diferentes.
La comunicación entre procesos (IPC, Inter-Process Communication) se refiere al mecanismo de comunicación entre diferentes procesos que se ejecutan en la misma computadora y se utiliza principalmente para realizar la transmisión de datos entre diferentes aplicaciones en la misma computadora. El mecanismo IPC se puede implementar a través de conductos con nombre, memoria compartida, colas de mensajes, semáforos, etc., todos los cuales se implementan a través de las API proporcionadas por el sistema operativo. La ventaja de la comunicación IPC es su alta velocidad y alta confiabilidad, pero solo puede comunicarse en la misma computadora.
La comunicación de socket es un método de comunicación basado en la red, que se realiza a través de un conjunto de protocolos TCP/IP estándar y puede realizar la transmisión de datos entre diferentes computadoras. La comunicación por socket es un método de comunicación orientado a la conexión. Durante el proceso de comunicación, se requieren pasos como el establecimiento de la conexión, la transmisión de datos y la desconexión de la conexión, por lo que su implementación es más complicada que la IPC. La ventaja de la comunicación Socket es que puede comunicarse entre diferentes computadoras y realizar la transmisión de datos entre redes, pero en comparación con IPC, la velocidad de la comunicación Socket será ligeramente más lenta.
En resumen, tanto la comunicación entre procesos como la comunicación de socket tienen sus propias ventajas y desventajas, y se debe seleccionar el método de comunicación apropiado de acuerdo con el escenario de aplicación específico. Si solo necesita comunicarse en la misma computadora, puede elegir el mecanismo IPC; si necesita comunicarse entre diferentes computadoras, puede elegir la comunicación Socket.

4) ¿Son la comunicación por socket y la comunicación por red un concepto?

La comunicación de socket y la comunicación de red son conceptos relacionados, pero no son completamente equivalentes.
La comunicación de red se refiere al proceso de transmisión de datos a través de una red informática, incluida una variedad de diferentes métodos y protocolos de comunicación, como TCP/IP, HTTP, FTP, etc. El propósito de la comunicación en red es transferir datos de una computadora a otra para que diferentes computadoras puedan transferir información entre sí.
La comunicación por socket es un método de comunicación basado en la red, que se realiza a través de un conjunto de protocolos TCP/IP estándar. En la comunicación Socket, la transmisión de datos debe ser procesada por la pila de protocolos de red, entre los cuales el protocolo TCP/IP es uno de los protocolos de red más utilizados. La comunicación por socket es un método de comunicación orientado a la conexión. Durante el proceso de comunicación, se requieren pasos como el establecimiento de la conexión, la transmisión de datos y la desconexión de la conexión, por lo que su implementación es más complicada que otros métodos de comunicación de red.
Por lo tanto, se puede decir que la comunicación Socket es una implementación específica de la comunicación de red, que se realiza a través del protocolo TCP/IP . La comunicación de red cubre una variedad de diferentes métodos y protocolos de comunicación, y la comunicación de socket es uno de los métodos de implementación.

5) ¿Cuál es la codificación de cadenas y la secuencia de bytes?
Cuando necesitamos transmitir datos a través de la red, debemos codificar los datos en una secuencia de bytes antes de que puedan transmitirse a través de la red. En Python, las cadenas se almacenan en Unicode, por lo que las cadenas deben codificarse como secuencias de bytes para transmitirse a través de la red.
Aquí hay un ejemplo, codificando una cadena como una secuencia de bytes:

s = “hola mundo”
b = s.codificar()

print(b) # b'hola mundo'

En este ejemplo, primero definimos una cadena s, luego usamos el método s.encode() para codificarla en una secuencia de bytes b y la imprimimos. El resultado es b'hola mundo', lo que indica que la cadena "hola mundo" se ha codificado como un objeto de tipo bytes.
Cuando el receptor recibe la secuencia de bytes, debe decodificarse en una cadena para su procesamiento. Aquí hay un ejemplo de decodificación de una secuencia de bytes en una cadena:

b = b'hola mundo'
s = b.decode()

imprimir(s) # hola mundo

En este ejemplo, primero definimos una secuencia de bytes b, luego usamos el método b.decode() para decodificarla en una cadena s e imprimirla. El resultado es hola mundo, lo que indica que la secuencia de bytes b'hola mundo' se ha decodificado en la cadena "hola mundo".

Supongo que te gusta

Origin blog.csdn.net/weixin_46274756/article/details/130146222
Recomendado
Clasificación