Python 多 TCP 套接字客户端通过多处理

问题描述 投票:0回答:1

所以,我正在尝试构建以下设置:

  • 有一个通过新线程处理传入连接的 TCP 服务器,
  • 有另一个进程,创建连接到该 TCP 服务器的新进程(TCP 客户端)。

我在 Windows 10 笔记本电脑上使用 Python 3.11.2。

对于大多数部分,它工作得很好。我只是有时会遇到 TCP 客户端进程问题。问题是某些进程没有创建。这不能一直重现,有时我在创建 5 个客户端进程时遇到问题,有时在创建 150 个时运行顺利。TCP 服务器 socket.listen() 积压足够高。

服务器代码

import threading
import socket

MAX_DATASIZE = 2048;

HOST = "127.0.0.1"
PORT = 5000

def handleSingleSocket(conn, addr):
    print("Client "+ str(addr[0]) + ": " + str(addr[1]) + " connected")
    data = conn.recv(MAX_DATASIZE)
    print(data)
    conn.sendall(data)
    conn.close()
    print("Client "+ str(addr[0]) + ": " + str(addr[1]) + " disconnected")

listSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listSocket.bind((HOST, PORT))
listSocket.listen(200)
print(f"Server listening on address {HOST} and port {PORT}")

while True:
    conn, addr = listSocket.accept()
    thread = threading.Thread(target=handleSingleSocket,args=(conn,addr))
    thread.start()
    print(f"[ACTIVE CONNECTIONS]: {threading.active_count() - 1}" )

Client Code(sleep是让所有客户端同时连接)

import socket
import multiprocessing
import time

MAX_DATASIZE = 2048;
HOST = "127.0.0.1"
PORT = 5000

def handleSingleConnection(sock: socket.socket, i):
    sock.connect((HOST, PORT))
    time.sleep(2)
    sock.sendall(f"Hello from Process {i}!".encode())
    result = sock.recv(MAX_DATASIZE)
    print(result)
    sock.close()

if (__name__ == '__main__'):
    for i in range(150):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        process = multiprocessing.Process(target=handleSingleConnection, args=(sock,i,))
        process.start()

有些连接没有创建。错误代码是这样的:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\spawn.py", line 120, in spawn_main 
    exitcode = _main(fd, parent_sentinel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\spawn.py", line 130, in _main      
    self = reduction.pickle.load(from_parent)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\reduction.py", line 238, in _rebuild_socket
    return ds.detach()
           ^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\resource_sharer.py", line 38, in detach
    with _resource_sharer.get_connection(self._id) as conn:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\resource_sharer.py", line 86, in get_connection
    c = Client(address, authkey=process.current_process().authkey)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\connection.py", line 499, in Client    c = PipeClient(address)
        ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\connection.py", line 701, in PipeClient
    _winapi.WaitNamedPipe(address, 1000)
FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden

所以,我想这与 Windows 上进程的生成创建有关,但我无法真正理解它。非常感谢您的帮助,在此先感谢! :)

python multiprocessing spawn
1个回答
1
投票

https://superfastpython.com/filenotfounderror-multiprocessing-python/

在本文的帮助下,我能够解决问题。

很明显,主函数先于子进程退出,所以找不到库中的文件。

文章定义了这种行为的三个前提条件:

  1. 使用“spawn”启动方法创建新进程。
  2. 与一个或多个进程共享一个并发原语。
  3. 主进程在子进程完全启动之前退出。

有趣的是,我没有使用并发原语,但仍然面临这个问题。

在开始之前将进程附加到列表中,然后在主函数中执行后加入它们,就可以了。

if __name__ == '__main__':
    plist = []
    for i in range(200):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        process = multiprocessing.Process(target=handleSingleConnection, args=(sock,i))
        plist.append(process)
        process.start()
    for p in plist:
        p.join()
© www.soinside.com 2019 - 2024. All rights reserved.