如何将我的 Kivy 客户端连接到服务器(TCP、套接字) [英] How connect my Kivy client to a server (TCP, Sockets)

查看:33
本文介绍了如何将我的 Kivy 客户端连接到服务器(TCP、套接字)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,作为我的项目(2D 多人纸牌游戏)的一部分,我想出了如何在线托管和运行服务器脚本.我的计划是让两个单独的 kivy 客户端连接到服务器(这将只是一个带有命令的脚本).

So as part of my project (2D Multiplayer Card Game), I've figured out how to host and run a server script online. My plan is to have two separate kivy clients connect to the server (which will just be a script with commands).

但是我对操作顺序有些困惑,因为我认为客户端连接可能与消息循环发生冲突,所以我想知道是否有人可以基本上告诉我我应该是什么正在做:

However I'm somewhat confused about the order of operations because I think the client connection is potentially in conflict with the message loop so I'm wondering if someone could basically tell me what I should be doing:

我将把它用作我的服务器脚本:

I'm going to be using this as my 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' + "
"
    clientsocket.send(msg.encode('ascii'))
    clientsocket.close()

这是我的客户端连接函数

This is my client connection function

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

注意:我知道服务器和客户端在功能上并不完全一致,但如果我现在至少可以确认连接,我可以从那里开始工作.

Note: I understand that the server and client aren't perfectly aligned in functions but provided I can at least a connection confirmation for now, I can work from there.

我基本上想知道如何将这段代码放入这样的简单 kivy 应用程序中:

I'm basically wondering how do I put this code into a simple kivy app like this:

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

我最好的猜测是你想要:

My best guess is that you want to:

  • 在打开客户端之前建立连接
  • 在您运行客户端实例(即 BoxApp(server).run()?)时,将服务器连接传递给主要小部件(在本例中为 Box 小部件)
  • 在 BoxWidget 的消息循环函数中使用该连接

我也知道 Kivy 已经内置了 Twisted 解决方案,但我在 python 2-3 差异方面遇到了麻烦.

I also understand that Kivy has built in solutions with Twisted but I'm having trouble with the python 2-3 differences.

感谢您的阅读.

澄清一下:我现在要做的就是打开一个空白窗口,并将确认消息发送到命令行(或在窗口中显示标签失败).

Just to clarify: All I want to do right now is open a blank window and also have a confirmation message sent to the command line (or failing that a label in the window).

推荐答案

我有一个使用按钮的基本版本.无论是在本地机器上还是在线上.由于必须启动回复,因此该解决方案可能不适用于许多实时应用程序甚至聊天服务器.但是,对于我的多人纸牌游戏目标来说,只要有适当的条件就足够了.

I got a basic version of it working with buttons. Both on local machine and online. This Solution is likely not viable for many real time apps or even a chat server since the reply has to be initiated. However for my goal of a multiplayer card game it should more than suffice with proper conditionals.

本地机器测试视频

在视频中,我谈到了双击.我刚刚意识到这是因为第一次单击使窗口重新成为焦点.

In the video I talk about double clicking. I have just realized this is because the first click is putting the window back in focus.

编辑 2:在 kv 文件中使用 TextInput 而不是 Python 文件中的输入.

EDIT 2: Using TextInput in kv file instead of input in Python file.

服务器脚本:

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

这是一个非常简单的服务器.监听单个客户端,确认连接,打开发送和接收消息循环.

This is a pretty simple server. Listen for a single client, confirm connection, open a send and receive message loop.

这是一个并不复杂的客户端脚本:

This is the client script which isn't hugely complicated really:

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

在未来的迭代中,我将用条件语句替换打印语句(即客户端 1 是否抽了牌?如果是,客户端 2 的对手抽了一张面朝下的牌等).

In future iterations, I'll be replacing print statements with conditionals (ie did client one draw a card? if so client 2's opponent draws a face-down card etc).

现在相对初级,但您可以从这里做很多事情.

Relatively rudimentary as it is now but there is a lot you could do from here.

这篇关于如何将我的 Kivy 客户端连接到服务器(TCP、套接字)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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