python多线程服务器 [英] python multithreaded server

查看:81
本文介绍了python多线程服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要编程的是一个简单的多线程python游戏服务器,很有趣.沮丧之后,我无法弄清测试客户端连接为什么超时.这是我的server.py代码:

What I'm trying to program is a simple multithreaded python game server for fun. After much frustration I've not been able to figure out why my test client connection times out. Here's my server.py code:

    import socket
import threading
import clientThread
import struct
import string

class Server:
    def __init__(self):
        self.HOST = 'localhost'
        self.PORT = 22085
        self.BUFFIZE = 1024
        self.ADDRESS = (self.HOST,self.PORT)
        self.clientList = []
        input("Press enter to start the server. . .")
        self.running = True
        self.serverSock = socket.socket()
        self.serverSock.bind(self.ADDRESS)
        self.serverSock.listen(2)
        self.clientThread = clientThread.clientThread(self)
        print("Starting client thread. . .")
        self.clientThreadObj = threading.Thread(target = self.clientThread.start, args = (self))
        print("Awaiting connections. . .")
        while self.running:
            clientInfo = self.serverSock.accept()
            print("Client connected from %s." % clientInfo[1])
            # Append to clientThread list...

        self.serverSock.close()
        print("- end -")

serv = Server()

服务器启动现有连接的线程并开始侦听.为现有连接构建的线程clientThread循环遍历客户端对象列表,这些对象目前不执行任何操作,它们只是体系结构.这是clientThread.py

The server starts the thread for existing connections and starts listening. The thread built for existing connections, clientThread, loops through a list of client objects which for now do nothing, they are simply architectural. Here is the clientThread.py

import socket
import threading
import struct
import string

class clientThread:
    def __init__(self, serv):
        self.server = serv
        self.clientList = []
        self.running = True
        print("Client thread created. . .")
    def start(self):
        print("Beginning client thread loop. . .")
        while self.running:
            for client in self.clientList:
                message = client.sock.recv(self.server.BUFFSIZE)
                if message != None and message != "":
                    client.update(message)

最后,非常简单的客户端对象:

And finally, the very simple client object:

import string

class clientObject:
    def start(self,clientInfo):
        self.sock = clientInfo[0]
        self.address = clientInfo[1]
    def update(self,message):
        self.sock.send("Testamundo.\r\n".encode())

现在,这里的问题是我的客户端甚至无法连接到我的服务器.它只是超时.这是我的简单客户端测试的代码:

Now, the problem here is that my client can't even connect to my server. It simply times out. Here is the code for my simple client test:

import socket
import string

address = ("192.168.1.1",22085)
mySocket = socket.socket()

mySocket.connect(address)
print("Connected successfully!")

这将在连接到地址的行上返回连接尝试失败,因为连接的用户在一段时间后未正确响应,或者建立的连接失败,因为连接的主机未能响应".

This returns, on the line that connects to address, "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond".

有什么建议吗?谢谢!抱歉,对于所有这些代码,我不确定是否需要全部发布,所以我认为它不会造成太大的伤害.

Any suggestions? Thanks! Sorry for all this code, I wasn't sure if I needed to post it all or not, so I figured it couldn't hurt too much.

推荐答案

您有两个系统吗?服务器系统的IP是否为192.168.1.1?如果只有一个系统,则本地主机地址为127.0.0.1.这是我必须对您的代码进行的第一个更改,以便在同一系统上运行服务器和客户端时获得连接.

Do you have two systems? Does the server system have an IP of 192.168.1.1? If you only have one system, the localhost address is 127.0.0.1. That was the first change I had to make to your code to get a connection when running the server and client on the same system.

另一个问题是您的客户端线程实际上没有启动.由于您需要客户端线程类,因此下面是声明和启动它的方法:

Another issue is your client thread doesn't actually start. Since you want a client thread class, here's how to declare and start it:

  1. threading.Thread的子类.
  2. 针对您的行为覆盖__init__,但首先在基类中调用__init__.
  3. 覆盖run进行线程工作.
  4. 创建实例并调用其start方法.
  1. Subclass from threading.Thread.
  2. Override __init__ for your behavior, but call __init__ in the base class first.
  3. Override run for the thread work.
  4. Create an instance and call its start method.

另一个问题是,如果客户端未发送任何数据,则recv会阻塞,因此,如果您尝试连接多个客户端,则它将挂在客户端列表的循环中.每个客户端都需要一个线程,或者使用select.select来查询客户端套接字以进行读/写准备.

Another problem is recv blocks if the client hasn't sent any data, so if you try to connect multiple clients it will hang in your loop over the client list. You'll need a thread per client or use select.select to query the client sockets for read/write readiness.

下面是更改的代码,只有一个客户端可以响应,但是需要处理多个客户端.它还需要建立一个协议来处理消息. TCP是一种流协议(无消息边界),因此发送"abc"和"123"可能会导致接收到"abc123"或"ab"和"c123"等.它必须处理关闭连接并从客户端列表中删除客户端对象.

Below is the changed code that got a single client to respond, but it needs work to handle multiple clients. It also needs to set up a protocol to handle messages. TCP is a streaming protocol (no message boundaries), so a send of 'abc' and '123' could result in a receive of 'abc123' or 'ab' and 'c123', etc. It'll have to handle closing the connections and remove the client objects from the client list as well.

祝你好运!您将学到很多知识,从头开始了解如何进行所有这些操作.还要查看socketserver.py库以获取示例代码.

Good luck! You'll learn a lot figuring out how to do all this from scratch. Look at the socketserver.py library as well for example code.

import socket
import threading
import struct
import string

class clientThread(threading.Thread):
    def __init__(self, serv):
        threading.Thread.__init__(self)
        self.server = serv
        self.clientList = []
        self.running = True
        print("Client thread created. . .")
    def run(self):
        print("Beginning client thread loop. . .")
        while self.running:
            for client in self.clientList:
                message = client.sock.recv(self.server.BUFFSIZE)
                if message != None and message != "":
                    client.update(message)

class clientObject(object):
    def __init__(self,clientInfo):
        self.sock = clientInfo[0]
        self.address = clientInfo[1]
    def update(self,message):
        self.sock.send("Testamundo.\r\n".encode())

class Server(object):
    def __init__(self):
        self.HOST = 'localhost'
        self.PORT = 22085
        self.BUFFSIZE = 1024
        self.ADDRESS = (self.HOST,self.PORT)
        self.clientList = []
        input("Press enter to start the server. . .")
        self.running = True
        self.serverSock = socket.socket()
        self.serverSock.bind(self.ADDRESS)
        self.serverSock.listen(2)
        self.clientThread = clientThread(self)
        print("Starting client thread. . .")
        self.clientThread.start()
        print("Awaiting connections. . .")
        while self.running:
            clientInfo = self.serverSock.accept()
            print("Client connected from {}.".format(clientInfo[1]))
            self.clientThread.clientList.append(clientObject(clientInfo))

        self.serverSock.close()
        print("- end -")

serv = Server()

clnt.py

import socket
import string

address = ('localhost',22085)
mySocket = socket.socket()

mySocket.connect(address)
print("Connected successfully!")
mySocket.send('blah'.encode())
print(mySocket.recv(1024))

输出(srv.py)

Press enter to start the server. . .
Client thread created. . .
Starting client thread. . .
Beginning client thread loop. . .
Awaiting connections. . .
Client connected from ('127.0.0.1', 52850).

输出(clnt.py)

Connected successfully!
b'Testamundo.\r\n'

这篇关于python多线程服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆