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