修改服务器';来自客户端的s变量';s线程(线程,python)

修改服务器';来自客户端的s变量';s线程(线程,python),python,multithreading,Python,Multithreading,我用Python实现了一个简单的网络“游戏”——服务器绘制一个随机数,然后客户端尝试猜测它。我的应用程序工作得很好,当客户机猜到数字时,它会与服务器断开连接(在客户机端处理) 然而,经过正确的猜测,数字仍然是一样的。我想修改这个应用程序,这样当客户机猜到这个数字时,服务器应该给一个新的数字赋值,这样其他客户机就应该猜到这个新的数字。我该怎么做 一些模板,只是为了引起对问题的注意: #!/usr/bin/env python from random import randint import s

我用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()

生成在服务器和所有客户端之间共享的随机数,应该只有该实例,因此这应该是类属性。
添加一个类函数
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):
         # ...

客户机应该每次调用这个
服务器.guess
函数。

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

作为一个附带问题(不是套接字专家),当您向客户机发送消息时,您可能希望将它们编码为字节对象(在处理程序的
run
方法中,我将
self.connection.send(msg)
更改为
self.connection.send(msg.encode())
。另外请注意,我使用了Python 3.6(主要改变打印报表的样式)

请参阅下面的代码:

#!/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.encode())
                            break
                        else :
                            msg = "Try again!"
                            self.connection.send(msg.encode())


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

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


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


    @classmethod
    def guess(cls, no):
        if cls.randnum == no:
            cls.randnum = randint(1, 1000)
            print("New number is ", cls.randnum )
            result = True
        else:
            result = False
        return result

    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 as  e:
            if self.server_socket:
                self.server_socket.close()
            sys.exit(1)


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

每个客户端都应该猜测自己的随机数,还是应该只有一个随机数所有客户端都应该猜测?@shanmuga:应该只有一个随机数所有客户端都需要猜测。当一个客户端猜测时,该数字应该会改变。但是当我试图在服务器端的
run
methodo中打印该数字时d、 我得到了一个错误:
namererror:global name'randnum'没有定义
@yak已经修复了一个输入错误(bug)。但是,当我尝试时,例如,在服务器的
运行中
do`c=ClientThread(connection,randnum)`它显示了我之前发布的错误。可能我做错了什么?您应该使用问题中显示的
self.randnum
来访问它。然后我在
附近遇到了另一个错误,如果cls.randnum==no:
,即:
AttributeError:class Server没有属性“randnum”
对不起,我忘记了赏金。但是我认为我的专业人士BLIM比Python更通用。在爪哇、C++、C等中如何实现同样的问题?问题是:当客户端需要用消息通知服务器时,总是有问题,服务器应该例如结束工作。我认为您的设计中的一个问题是将类方法和实例方法分离。例如,我认为
randint
应该属于您的服务器实例,因为它是此实例状态的一部分,并且在任何客户端发现后都必须进行修改。每次需要修改服务器实例的状态时(例如关闭它),它应该是一个实例方法。您可以使它与classmethod一起工作,但它可能并不优雅。