Python - [socket] Simple example of server abnormal restart processing Demo (2)

I. Introduction

When there is an abnormality in socket server communication, we need to do a restart procedure, and we can make choices based on specific scenarios.

2. Sample code

1. Restart the service

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()

In this example, we added an exception catching logic on the server side, closed the server-side socket when an exception occurred, and then waited for a period of time before reconnecting. It should be noted that in this example, only the socket.bind() method and socket.listen() method are used to catch and handle exceptions. If you need to catch and handle exceptions for other socket operations, you need to add them in the corresponding locations. Similar logic.
The running effect is as follows:
Insert image description here

2. Kill the process and restart the service

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()

running result:
Insert image description here

In this example, if an exception occurs on the server side, it prints an error message and closes the server side socketobject, then waits for a while and then restarts the server. This restart process is os.execv()implemented using functions, which can restart the current process and run a new Python program.
It should be noted that before restarting the service, the previous server socket must be closed, otherwise there may be a problem that the socket address has been occupied. Moreover, it is best to release all resources before restarting to avoid affecting the next server operation.

In addition, the restart interval in this example can be adjusted according to the actual situation. When running the program, you also need to pay attention to whether there are any abnormalities in the creation of processes and threads to ensure the operating efficiency of the CPU.

View the number of threads and processes

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())}")

The above is a simple example of [socket] server abnormal restart processing. I hope it will be helpful to you!

Guess you like

Origin blog.csdn.net/qq_43030934/article/details/132125145