【问题标题】:TCP Client Kivy App not connecting to ServerTCP 客户端 Kivy 应用程序未连接到服务器
【发布时间】:2020-11-16 03:31:20
【问题描述】:

我的服务器由笔记本电脑制成,我使用 kivy 应用程序作为客户端连接到该服务器。 当我在同一台笔记本电脑上使用服务器和客户端时,它可以工作。但是,我尝试在移动设备上运行它并没有连接。

我使用 Google Play 应用 TCP 客户端检查连接,并且连接成功。所以,我想服务器端没有问题。

这是我的 server.py

import socket
import sys
from pynput.keyboard import Key, Controller
import time

keyboard = Controller()

def releaseAll():
    time.sleep(0.3)
    keyboard.release(Key.up)
    keyboard.release(Key.down)
    keyboard.release(Key.left)
    keyboard.release(Key.right)

def pressKeyboard(str):
    if(str == "U"):
        keyboard.press(Key.up)
    elif(str == "D"):
        keyboard.press(Key.down)
    elif(str == "L"):
        keyboard.press(Key.left)
    elif(str == "R"):
        keyboard.press(Key.right)
    releaseAll()

# Create a TCP/IP socket for server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# name = socket.gethostname()
# print(name)
# ip = socket.gethostbyname(name)
# print(ip)

# Bind the socket to the port
serverAddress = ('192.168.0.104', 10000)
server.bind(serverAddress)

print("Server successfully created...")
print("Server listening at localhost at port 10000")

# Listen for incoming connections
server.listen(1)

while True:
    # Wait for a connection
    print("No clients connected with server.\nWaiting for client to connect...")
    connection, client_address = server.accept()
    print("Client requested to connect...")

    try:
        print("Client", client_address, "successfully connected...")

        # Receive 1 byte data "L", "U", "R", "D"
        while True:
            dataByte = connection.recv(1)
            if not dataByte:
                break
            dataChar = dataByte.decode('utf-8')
            print(dataChar)
            pressKeyboard(dataChar)      
    finally:
        # Close the connection
        connection.close()
        print("Connection lost from", client_address)

这是我来自 kivy 应用的 main.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from kivy.uix.label import Label
from kivy.uix.image import Image
import socket
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen


# import sys
# class MyButton(Button):
#     def on_release(self):
#         new_button = Button(text = 'hello')
#         self.ids.float_1.add_widget(new_button)

class TestApp(App):
    def __init__(self):
        App.__init__(self)
        self.l = ""
        self.showData = ""
        self.flag = False
        self.layout = FloatLayout()
        self.new_button = Button(background_color = (0,0,0,0),text = 'Connected to Server!',color = (0,0,0,1),pos_hint = {'center_x': 0.5, 'center_y' : 0.8},size_hint= (.20,.1))
        self.serverError = Button(background_color=(0, 0, 0, 0), text='Cannot connect to Server!', color=(0, 0, 0, 1),
                                 pos_hint={'center_x': 0.5, 'center_y': 0.8}, size_hint=(.20, .1))
        self.serverDisconnected = Button(background_color=(0, 0, 0, 0), text='Disconnected from Server!', color=(0, 0, 0, 1),
                                 pos_hint={'center_x': 0.5, 'center_y': 0.8}, size_hint=(.20, .1))
        self.img =  Image(source = 'bground.jpg',allow_stretch = True, keep_ratio = True)

    def build(self):
        #layout = FloatLayout()
        #layout2 = FloatLayout()
        #new_button = Button(text = 'hello',pos_hint = {'center_x': 0.5, 'center_y' : 0.9},size_hint= (.15,.1))
        self.layout.add_widget(self.img)
        connectbtn = Button(background_color = (255,255,0,0.4),text="Connect", pos_hint={'center_x': 0.2, 'center_y': 0.8},
                            size_hint=(.15, .1), on_press=self.cconnect,on_release = self.ccnn)
        self.layout.add_widget(connectbtn)

        disconnectbtn = Button(background_color = (255,255,0,0.4),text="Disconnect",pos_hint={'center_x': 0.8, 'center_y': 0.8},
                               size_hint=(.15, .1), on_press=self.cdisconnect)
        self.layout.add_widget(disconnectbtn)

        upbtn = Button(background_color = (0,0,0,0.7),text='Up', font_size=20, pos_hint={'center_x': 0.5, 'center_y': 0.45},
                       size_hint=(.1, .1), on_press=self.up_press)
        self.layout.add_widget(upbtn)

        dwnbtn = Button(background_color = (0,0,0,0.7),text='Down', font_size=20, pos_hint={'center_x': 0.5, 'center_y': 0.15},
                        size_hint=(.1, .1), on_press=self.dwn_press)
        self.layout.add_widget(dwnbtn)

        rbtn = Button(background_color = (0,0,0,0.7),text='Right', font_size=20, pos_hint={'center_x': 0.65, 'center_y': 0.3},
                      size_hint=(.1, .1), on_press=self.r_press)
        self.layout.add_widget(rbtn)

        lbtn = Button(background_color = (0,0,0,0.7),text='Left', font_size=20, pos_hint={'center_x': 0.35, 'center_y': 0.3},
                      size_hint=(.1, .1), on_press=self.l_press)
        self.layout.add_widget(lbtn)
        return self.layout

    def ccnn(self, obj):
        self.flag = True

    def cconnect(self, obj):
        try:
            # Create a TCP/IP socket for client
            self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # Connect the socket to the port where the server is listening
            self.server_address = ('192.168.0.104', 10000)
            self.client.connect(self.server_address)
            print("Connecting to localhost, port 10000")
            # conn = Label(text="Connected")
            self.layout.remove_widget(self.serverDisconnected)
            self.layout.remove_widget(self.serverError)
            self.layout.add_widget(self.new_button)
            Clock.schedule_interval(self.send_client, 0.3)
        except:
            self.layout.remove_widget(self.new_button)
            self.layout.remove_widget(self.serverDisconnected)
            self.layout.add_widget(self.serverError)
            print("Cannot Connect to Server..")

    def cdisconnect(self, obj):
        Clock.unschedule(self.send_client)
        self.client.close()
        self.showData = "Not Connected to server.."
        self.layout.remove_widget(self.new_button)
        self.layout.remove_widget(self.serverError)
        self.layout.add_widget(self.serverDisconnected)
        print("Disconnected from the Server..")

    def up_press(self, obj):
        # l.append(+1)
        self.l = 'U'
        print('Up button is pressed')

    def dwn_press(self, obj):
        # l.append(-1)
        self.l = 'D'
        print('Down button is pressed')

    def r_press(self, obj):
        # l.append(+2)
        self.l = 'R'
        print('Right button is pressed')

    def l_press(self, obj):
        # l.append(-2)
        self.l = 'L'
        print('Left button is pressed')

    def send_client(self, obj):
        val = ""
        if self.l == "":
            val = "Q"
        else:
            val = self.l
        self.l = ""
        try:
            print("Sending Message", val)
            # Send string as bytes to server
            self.client.sendall(str.encode(val))
        except:
            self.showData = "Error while sending data to server.."
            print("Error while sending data to server..")


TestApp().run()

请帮我解决我的问题。 提前谢谢你。

【问题讨论】:

    标签: tcp kivy tcpclient


    【解决方案1】:

    但是,我尝试在移动设备上运行它...

    serverAddress = ('192.168.0.104', 10000)
    

    此地址是private IP address。无法从网络外部访问本地网络中的这样一个私有 IP 地址,特别是不能从移动网络访问。为了使您的服务器可以从移动网络访问,它必须首先可以从外部访问,例如在端口转发的帮助下或通过使用像ngrok 这样的外部转发器。然后客户端必须使用服务器的外部可见的地址和端口,而不是内部的。

    【讨论】:

    • 谢谢,但事实并非如此。我发现使用 buildozer 提取的 Kivy 应用程序对连接有限制。我取消了它们的注释,它对我有用。
    • @MasoomRaj:按照设计,从移动网络连接到这个内部 IP 地址仍然是不可能的。它可能在带有 WiFi 的 LAN 上工作,但不能在移动网络上工作。
    猜你喜欢
    • 2021-08-12
    • 2022-01-16
    • 2019-06-06
    • 2019-06-18
    • 2017-02-24
    • 1970-01-01
    • 2021-11-07
    • 2019-02-14
    • 2018-05-24
    相关资源
    最近更新 更多