因此,作为我的项目(2D多人纸牌游戏)的一部分,我已经弄清楚如何在线托管和运行服务器脚本。我的计划是让两个独立的kivy客户端连接到服务器(这只是一个带命令的脚本)。
然而,我对操作的顺序感到有些困惑,因为我认为客户端连接可能与消息循环冲突,所以我想知道是否有人能告诉我我该做什么:
我将使用它作为我的serverscript:
import socket
serversocket = socket.socket()
host = 'INSERTIPHERE'
port = PORTHERE
serversocket.bind(('', port))
serversocket.listen(1)
while True:
clientsocket,addr = serversocket.accept()
print("got a connection from %s" % str(addr))
msg = 'Thank you for connecting' + "\r\n"
clientsocket.send(msg.encode('ascii'))
clientsocket.close()
这是我的客户端连接功能
def Main():
host = 'INSERTIPHERE'
port = PORTHERE
mySocket = socket.socket()
mySocket.connect((host, port))
message = input(' -> ')
while message != 'q':
mySocket.send(message.encode())
data = mySocket.recv(1024).decode()
print('Received from server: ' + data)
message = input(' -> ')
mySocket.close()
注意:我知道服务器和客户端在功能上没有完全对齐,但是我现在至少可以进行连接确认,我可以在那里工作。
我基本上想知道如何将此代码放入这样一个简单的kivy应用程序中:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class BoxWidget(BoxLayout):
pass
class BoxApp(App):
def build(self):
return BoxWidget()
if __name__ == '__main__':
BoxApp().run()
我最好的猜测是你要:
我也明白Kivy已经内置了Twisted的解决方案,但是我遇到了python 2-3差异的问题。
感谢您的阅读。
只是为了澄清:我现在想要做的就是打开一个空白窗口,并且还有一条确认消息发送到命令行(或者在窗口中没有标签)。
答案 0 :(得分:0)
您可以使用线程,这样就不会在kivy中断主线程 我重写了你的例子,所以你从服务器发送的是标签的文本。
server.py
import socket
serversocket = socket.socket()
host = 'localhost'
port = 54545
serversocket.bind(('', port))
serversocket.listen(1)
clientsocket,addr = serversocket.accept()
print("got a connection from %s" % str(addr))
while True:
msg = input("> ") + "\r\n"
clientsocket.send(msg.encode('ascii'))
client.py
import socket
class MySocket:
def __init__(self,host="localhost",port=54545):
self.sock = socket.socket()
self.sock.connect((host, port))
def get_data(self):
return self.sock.recv(1024)
main.py
from kivy.app import App
from kivy.uix.label import Label
from client import *
from threading import Thread
class MyLabel(Label):
def __init__(self, **kwargs):
super(MyLabel,self).__init__(**kwargs)
self.sock = MySocket()
Thread(target=self.get_data).start()
def get_data(self):
while True:
self.text = self.sock.get_data()
class BoxApp(App):
def build(self):
return MyLabel()
if __name__ == '__main__':
BoxApp().run()
现在只需在一个终端中运行server.py,然后从另一个终端运行main.py
答案 1 :(得分:0)
我有一个使用按钮的基本版本。在本地机器和在线。由于必须启动回复,因此对于许多实时应用甚至聊天服务器而言,此解决方案可能不可行。然而,对于我的多人纸牌游戏的目标,它应该足以满足条件。
video of test on local machine
编辑:在视频中我谈到了双击。我刚刚意识到这是因为第一次点击是让窗口重新聚焦。编辑2:在kv文件中使用TextInput而不是在Python文件中输入。
服务器脚本:
import socket
def Main():
host = '127.0.0.1'
port = 7000
mySocket = socket.socket()
mySocket.bind((host,port))
mySocket.listen(1)
conn, addr = mySocket.accept()
print ("Connection from: " + str(addr))
message = 'Thank you connecting'
conn.send(message.encode())
while True:
data = conn.recv(1024).decode()
strdata = str(data)
print(strdata)
reply = 'confirmed'
conn.send(reply.encode())
mySocket.close()
if __name__ == '__main__':
Main()
这是一个非常简单的服务器。侦听单个客户端,确认连接,打开发送和接收消息循环。
这是客户端脚本,实际上并不是非常复杂:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
import socket
class BoxWidget(BoxLayout):
s = socket.socket()
host = '127.0.0.1'
port = 7000
display = ObjectProperty()
def connect_to_server(self):
# called by a Button press
# Connects to the server
self.s.connect((self.host, self.port))
# Receives confirmation from Server
data = self.s.recv(1024).decode()
# Converts confirmation to string
strdata = str(data)
# Prints confirmation
print(strdata)
def send_message(self):
# Is called by the function below
# Encodes and sends the message variable
self.s.send(self.message.encode())
# Waits for a reply
self.receive_message()
def message_to_send(self):
# Defines Message to send
self.message = self.display.text
# Calls function to send the message
self.send_message()
# Note
# When I used message = input directly in send_message,
# the app would crash. So I defined message input
# in its own function which then calls the
# send function
# message_to_send is the function actually
# called by a button press which then
# starts the chain of events
# Define Message, Send Message, get Reply
def receive_message(self):
# Decodes a reply
reply = self.s.recv(1024).decode()
# Converts reply to a str
strreply = str(reply)
# prints reply
print(strreply)
class ServerApp(App):
def build(self):
box = BoxWidget()
return box
if __name__ == '__main__':
ServerApp().run()
编辑:忘记包含kv文件
<BoxWidget>:
display: display
Button:
text: 'Hello'
on_press: root.message_to_send()
Button:
text: 'Connect'
on_press: root.connect_to_server()
TextInput:
id: display
在未来的迭代中,我将用条件替换打印语句(即客户端是否绘制了一张卡?如果客户2的对手绘制了面朝下的卡等)。
现在相对简陋,但你可以从这里做很多事情。