【问题标题】:How to fix multiprocessing echo server to handle multiple clients如何修复多处理回显服务器以处理多个客户端
【发布时间】:2019-01-11 05:40:48
【问题描述】:

我想创建一个多处理回显服务器。我目前正在使用 telnet 作为我的客户端向我的回显服务器发送消息。目前我可以处理一个 telnet 请求并回显响应。我最初认为我应该在创建套接字时初始化 pid。对吗?

如何允许多个客户端使用多处理连接到我的服务器。

#!/usr/bin/env python
import socket
import os
from multiprocessing import Process

def create_socket():

    # Create socket
    sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Port for socket and Host
    PORT = 8002
    HOST = 'localhost'

    # bind the socket to host and port
    sockfd.bind((HOST, PORT))
    # become a server socket
    sockfd.listen(5)

    start_socket(sockfd)

def start_socket(sockfd):

    while True:

        # Establish and accept connections woth client
        (clientsocket, address) = sockfd.accept()

         # Get the process id.
        process_id = os.getpid()
        print("Process id:", process_id)

        print("Got connection from", address)
        # Recieve message from the client
        message = clientsocket.recv(2024)
        print("Server received: " + message.decode('utf-8'))
        reply = ("Server output: " + message.decode('utf-8'))
        if not message:
            print("Client has been disconnected.....")
            break
        # Display messags.
        clientsocket.sendall(str.encode(reply))

    # Close the connection with the client
    clientsocket.close()

if __name__ == '__main__':

    process = Process(target = create_socket)     
    process.start()

【问题讨论】:

    标签: python multithreading sockets python-multiprocessing


    【解决方案1】:

    了解哪些是阻塞系统调用,哪些不是,这可能是个好主意。 listen 例如没有阻塞,accept 正在阻塞一个。所以基本上 - 您通过Process(..) 创建了一个进程,该进程在accept 处阻塞,并且在建立连接时 - 处理该连接。

    您的代码应该有一个结构 - 类似于以下(伪代码)

    
    def handle_connection(accepted_socket):
        # do whatever you want with the socket
        pass
    
    def server():
    
        # Create socket and listen to it. 
        sock = socket.socket(....)
        sock.bind((HOST, PORT))
        sock.listen(5)
    
        while True:
            new_client = sock.accept() # blocks here.
    
            # unblocked 
            client_process = Process(target=handle_connection, args=(new_client))
            client_process.start()
    
    

    我还必须提到,虽然这是了解如何完成事情的好方法,但对于每个连接都启动一个新流程并不是一个好主意。

    【讨论】:

    • 在handle_connection() 中我会在哪里回显消息?因此,我不需要 main 以及在哪里调用 client_process.start()
    • 是的,在handle_connection 中,您应该回显该消息。你可以马上做client_process.start
    • 另外,我应该把 os.getpid() 放在哪里?
    • 为什么要放os.getpid()os.getpid() - 将返回当前进程的进程 ID。所以无论你想要PID 的哪个进程,你都应该把os.getpid() 放在那里。所以如果你想知道客户端进程的pid,把它放在handle_connection
    • @pennyBoy 不要放弃。当您进入“出于某种原因”阶段时,乐趣就开始了。你可以在地平线上看到它。 :)
    【解决方案2】:

    设置服务器、绑定、监听等的初始部分(您的create_socket)应该在主进程中。

    一旦您accept 并获得了一个套接字,您应该生成一个单独的进程来处理该连接。换句话说,你的start_socket 应该在一个单独的进程中产生并且应该永远循环。

    【讨论】:

    • 有点效果。但现在每当我创建一个新进程时它似乎都会阻塞。我会更新我的代码。
    猜你喜欢
    • 2015-02-24
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多