Python - [socket] Ejemplo simple de procesamiento de reinicio anormal del servidor Demostración (2)

I. Introducción

Cuando hay una anomalía en la comunicación del servidor de socket, debemos realizar un procedimiento de reinicio y podemos tomar decisiones basadas en escenarios específicos.

2. Código de muestra

1. Reinicie el servicio

import socket
import time
import sys
import traceback

HOST = '127.0.0.1'  # 服务器IP地址
PORT = 8080  # 服务器端口号
BACKLOG = 5  # 服务器监听队列大小,即最多同时接收多少个客户端连接
RECONNECT_INTERVAL = 5  # 重连间隔,单位:秒


def start_server():
    while True:
        try:
            # 创建一个 TCP/IP socket 对象
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # 绑定服务器 IP 地址和端口号
            server_socket.bind((HOST, PORT))

            # 开始监听客户端连接请求
            server_socket.listen(BACKLOG)

            print('服务器启动,监听端口:%s' % PORT)

            while True:
                # 等待客户端连接
                print('等待客户端连接...')
                client_socket, client_address = server_socket.accept()

                try:
                    print('新客户端连接,地址:%s' % str(client_address))

                    # 读取客户端发送的数据
                    data = client_socket.recv(1024)
                    print('Received data:', data.decode())

                    # 向客户端发送数据
                    message = 'Welcome to my server!'
                    client_socket.sendall(message.encode())

                except Exception as e:
                    print('客户端连接异常,错误信息:%s' % e)

                finally:
                    # 关闭客户端连接
                    client_socket.close()
                    print('客户端连接已关闭')

        except Exception as e:
            print('服务器异常,错误信息:%s' % e)
            traceback.print_exc()

            # 关闭服务端 socket
            server_socket.close()
            print('{}s后尝试重连服务器...'.format(RECONNECT_INTERVAL))
            time.sleep(RECONNECT_INTERVAL)


if __name__ == '__main__':
    # 启动服务器
    start_server()

En este ejemplo, agregamos una lógica de captura de excepciones en el lado del servidor, cerramos el socket del lado del servidor cuando ocurrió una excepción y luego esperamos un período de tiempo antes de volver a conectarnos. Cabe señalar que en este ejemplo, solo se utilizan el método socket.bind() y el método socket.listen() para capturar y manejar excepciones. Si necesita capturar y manejar excepciones para otras operaciones de socket, debe agregarlas en las ubicaciones correspondientes Lógica similar.
El efecto de ejecución es el siguiente:
Insertar descripción de la imagen aquí

2. Finalice el proceso y reinicie el servicio.

import multiprocessing
import os
import threading
import time
import sys
import traceback
import socket
import signal

HOST = '127.0.0.1'  # 服务器IP地址
PORT = 8080  # 服务器端口号
BACKLOG = 5  # 服务器监听队列大小,即最多同时接收多少个客户端连接
RECONNECT_INTERVAL = 3  # 重连间隔,单位:秒


def start_server():
    while True:
        try:
            # 创建一个 TCP/IP socket 对象
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # 绑定服务器 IP 地址和端口号
            server_socket.bind((HOST, PORT))

            # 开始监听客户端连接请求
            server_socket.listen(BACKLOG)

            print('服务器启动,监听端口:%s' % PORT)

            while True:
                # 等待客户端连接
                print('等待客户端连接...')
                client_socket, client_address = server_socket.accept()

                try:
                    print('新客户端连接,地址:%s' % str(client_address))

                    # 读取客户端发送的数据
                    data = client_socket.recv(1024)
                    print('Received data:', data.decode())

                    # 向客户端发送数据
                    message = 'Welcome to my server!'
                    client_socket.sendall(message.encode())

                except Exception as e:
                    print('客户端连接异常,错误信息:%s' % e)

                finally:
                    # 关闭客户端连接
                    client_socket.close()
                    print('客户端连接已关闭')

        except Exception as e:
            print('服务器异常,错误信息:%s' % e)

            # 关闭服务器端 socket
            server_socket.close()
            print('服务器即将重启...')

            # 等待一段时间后重启服务器
            time.sleep(RECONNECT_INTERVAL)
            os.execv(sys.executable, ['python'] + sys.argv)
            # os.kill(os.getpid(), signal.SIGTERM)
            # print(f"Process {multiprocessing.current_process().pid}: {threading.active_count()} threads")
            # print(f"Process {threading.current_thread()}: {threading.active_count()} threads")
            # print(f"Total threads: {threading.active_count()}")
            # print(f"Total processes: {len(multiprocessing.active_children())}")


if __name__ == '__main__':
    # 启动服务
    start_server()

resultado de ejecución:
Insertar descripción de la imagen aquí

En este ejemplo, si se produce una excepción en el lado del servidor, imprime un mensaje de error y cierra el socketobjeto del lado del servidor, luego espera un momento y luego reinicia el servidor. Este proceso de reinicio se os.execv()implementa mediante funciones, que pueden reiniciar el proceso actual y ejecutar un nuevo programa Python.
Cabe señalar que antes de reiniciar el servicio, se debe cerrar el socket del servidor anterior, de lo contrario puede haber un problema de que la dirección del socket haya estado ocupada. Además, es mejor liberar todos los recursos antes de reiniciar para evitar afectar la siguiente operación del servidor.

Además, el intervalo de reinicio en este ejemplo se puede ajustar de acuerdo con la situación real. Al ejecutar el programa, también debe prestar atención a si hay alguna anomalía en la creación de procesos y subprocesos para garantizar la eficiencia operativa de la CPU. .

Ver el número de subprocesos y procesos.

print(f"Process {
      
      multiprocessing.current_process().pid}: {
      
      threading.active_count()} threads")
print(f"Process {
      
      threading.current_thread()}: {
      
      threading.active_count()} threads")
print(f"Total threads: {
      
      threading.active_count()}")
print(f"Total processes: {
      
      len(multiprocessing.active_children())}")

Lo anterior es un ejemplo simple del procesamiento de reinicio anormal del servidor [socket]. ¡Espero que le sea útil!

Supongo que te gusta

Origin blog.csdn.net/qq_43030934/article/details/132125145
Recomendado
Clasificación