从客户端的线程(线程,python)

时间:2017-05-03 10:53:39

标签: python multithreading

我实施了一个简单的网络游戏'在Python中 - 服务器绘制一个随机数,然后客户端尝试猜测它。我的应用程序运行良好,当客户端猜出数字时,它与服务器断开连接(它在客户端处理)。

然而,在正确猜测之后,数字仍然相同。我想修改应用程序,这样当客户端猜出数字时,服务器应该输出一个新的数字,所以其他客户端应该猜测新的数字。我怎么能这样做?

一些模板,只是为了引起对问题的关注:

#!/usr/bin/env python

from random import randint
import socket, select
from time import gmtime, strftime
import threading
import sys

class Handler(threading.Thread):
    def __init__(self, connection, randomnumber):
        threading.Thread.__init__(self)
        self.connection = connection
        self.randomnumber = randomnumber

    def run(self):
        while True:
            try:
                data = self.connection.recv(1024)

                if data:

                    print data

                    try:
                        num = int(data)

                        if Server.guess(num) :
                            msg = "You won! This is the right number!"
                            self.connection.send(msg)
                            break
                        else :
                            msg = "Try again!"
                            self.connection.send(msg)


                    except ValueError, e:
                        msg = "%s" % e
                        self.connection.send(msg)
                else:
                    msg = "error"
                    self.connection.send(msg)

            except socket.error:
                self.connection.close()
                break
        self.connection.close()


class Server:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port
        self.address = (self.ip, self.port)
        self.server_socket = None
        self.randnum = randint(1, 100)


    @classmethod
    def guess(cls, no):
        if cls.randnum == no:
            cls.randnum = randint(1, 1000)
            result = True
        else:
            result = False
        return reslut

    def run(self):
        try:
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server_socket.bind((self.ip, self.port))
            self.server_socket.listen(10)

            print 'Num is %s' % self.randnum

            while True:
                connection, (ip, port) = self.server_socket.accept()

                c = Handler(connection, self.randnum)
                c.start()

        except socket.error, e:
            if self.server_socket:
                self.server_socket.close()
            sys.exit(1)


if __name__ == '__main__':
    s = Server('127.0.0.1', 1234)
    s.run()

2 个答案:

答案 0 :(得分:3)

生成服务器和所有客户端之间共享的随机数,应该只有这个的实例,因此这应该是class属性。
添加一个类函数guess,在错误猜测时返回False,并在正确猜测时更改randnum并返回True

class Server:
    randnum = randint(1, 1000)  # class attribute created

    @classmethod
    def guess(cls, no):        # To be used "guess" if `no` attribute if the same as `cls.randnum`
        if cls.randnum == no:
            cls.randnum = randint(1, 1000)
            result = True
        else:
            result = False
        return result

    def __init__(self, ip, port):
         # ...

客户端每次都应调用此Server.guess函数。

答案 1 :(得分:1)

实际上,您的问题来自于您创建randnum作为实例方法(请参阅self.randnum),如@shanmuga所述,如果您只是将其声明为类属性,并删除实例方法它解决了你的问题(即直接在类中声明它)。

作为一个副问题(不是socket上的专家),当您向客户端发送消息时,您可能希望将它们编码为字节对象(在Handler的run方法中,我更改了{{ 1}}到self.connection.send(msg))。另请注意,我使用的是Python 3.6(主要是改变了打印语句的样式)

请参阅以下代码:

self.connection.send(msg.encode())