【问题标题】:How to make a simple multithreaded socket server in Python that remembers clients如何在 Python 中创建一个记住客户端的简单多线程套接字服务器
【发布时间】:2014-07-12 18:09:14
【问题描述】:

如何创建一个简单的 Python 回显服务器来记住客户端并且不会为每个请求创建一个新套接字?必须能够支持并发访问。我希望能够使用此客户端或类似客户端连接一次并持续发送和接收数据:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = raw_input("Server hostname or ip? ")
port = input("Server port? ")
sock.connect((host,port))
while True:
    data = raw_input("message: ")
    sock.send(data)
    print "response: ", sock.recv(1024)

即服务器在端口 50000 上运行,使用上面的客户端我希望能够做到这一点:

me@mine:~$ client.py
Server hostname or ip? localhost
Server Port? 50000
message: testa
response: testa
message: testb
response: testb
message: testc
response: testc

【问题讨论】:

    标签: python sockets python-2.7 echo-server


    【解决方案1】:

    您可以为每个客户端使用一个线程来避免阻塞client.recv(),然后使用主线程来监听新客户端。连接时,主线程会创建一个新线程,该线程只监听新客户端,并在 60 秒内不说话时结束。

    import socket
    import threading
    
    class ThreadedServer(object):
        def __init__(self, host, port):
            self.host = host
            self.port = port
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.sock.bind((self.host, self.port))
    
        def listen(self):
            self.sock.listen(5)
            while True:
                client, address = self.sock.accept()
                client.settimeout(60)
                threading.Thread(target = self.listenToClient,args = (client,address)).start()
    
        def listenToClient(self, client, address):
            size = 1024
            while True:
                try:
                    data = client.recv(size)
                    if data:
                        # Set the response to echo back the recieved data 
                        response = data
                        client.send(response)
                    else:
                        raise error('Client disconnected')
                except:
                    client.close()
                    return False
    
    if __name__ == "__main__":
        while True:
            port_num = input("Port? ")
            try:
                port_num = int(port_num)
                break
            except ValueError:
                pass
    
        ThreadedServer('',port_num).listen()
    

    客户端在 60 秒不活动后超时,必须重新连接。见函数ThreadedServer.listen()client.settimeout(60)这一行

    【讨论】:

    • 我发现这个有趣的简短问题是 self.sock.listen(5) 行负责允许的连接数量?所以基本上我可以一次接受 5 个客户,但不能更多,或者 5 个有什么用?
    • @Kev1n91 5 是 backlog 参数,它指定可以排队等待接受的连接数。在此处的文档中进行了解释:docs.python.org/2/library/socket.html#socket.socket.listen
    • Traceback (most recent call last): File "E:/myProto/threadedserver.py", line 36, in <module> ThreadedServer('',port_num).listen() File "E:/myProto/threadedserver.py", line 10, in __init__ self.sock.bind((self.host, self.port)) TypeError: an integer is required (got type str)
    • @cascading-style 我在 python 2.7 中写了这个,我猜你正在使用 python 3? input 在 python 3 中返回一个字符串 - 只需将 port_num 设为 int:port_num = int(port_num)
    猜你喜欢
    • 2013-07-06
    • 2021-07-19
    • 2020-05-24
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2019-01-06
    相关资源
    最近更新 更多