使用TCP

时间:2019-03-25 15:02:19

标签: python python-3.x tcp multiprocessing kivy

我是python编码方面的新秀,我正在尝试学习多处理来解决自己遇到的问题。

我有一个带有树莓派(linux)的项目,并且从另一台PC /设备(windows)尝试通过TCP连接在它们之间共享数据。我做了能正常工作的服务器/客户端代码(树莓派上的服务器和PC上的客户端)。

下一步是制作一个可视化应用程序(在这种情况下,我选择使用kivy),并通过该应用程序直接将数据从我的PC连接到树莓派,其中PC是直接来自python / kivy代码的客户端。 / p>

问题是,当我在奇异的应用程序中引入IP和PORT时,脚本正在连接我,但是立即杀死了服务器,我希望我的服务器一直一直处于活动状态。

另一个问题,假设服务器没有被代码杀死,在另一个名为send_data的函数中,我想将speed和angle变量发送到我的服务器,并且仍然连接到该服务器,并且该服务器还活着,所以我只选项是多处理。

树莓派服务器代码:

import socket

host = ''
port = int(input("Port: "))

speed = []
angle = []

def setupServer():
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   print ("Socket created")
   try:
      s.bind((host, port))
   except socket.error as msg:
      print(msg)
   print("Socket bind complete.")
   return s

def setupConnection():
   s.listen(1)
   conn, address = s.accept()
   print("Connected to: " +address[0] + ":" + str(address[1]))
   return conn

def dataTransfer(conn):
   global speed,angle

   data = conn.recv(1024)
   data = data.decode('utf-8')
   """ split the data """
   dataMessage = data.split(' ',1)
   speed = dataMessage[0]
   angle = dataMessage[1]

   print(speed)
   print(angle)

   if dataMessage[0] == 'exit':
       print("Client has left the server")
       break
   if dataMessage[0] == 'kill':
       print("Server is shutting down")
       s.close()
       break

   conn.close()


s = setupServer()

while True:
   try:
      conn = setupConnection()
      dataTransfer(conn)
   except:
      break

带有kivy模块的客户代码:

import kivy
import socket
import multiprocessing

kivy.require('1.10.1')

from kivy.app import App
from kivy.uix.button import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.config import Config
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty


Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '400')


class MyGrid(Widget):
    ip = ObjectProperty(None)
    port = ObjectProperty(None)
    speed = ObjectProperty(None)
    angle = ObjectProperty(None)

    def connecting(self):
        h = self.ip.text
        p = int(self.port.text)

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((h, p))
        self.lbl.text = "Connected to server!"

        return s

    def __init__(self):
        super(MyGrid, self).__init__()

    def send_data(self):
        h = self.ip.text
        p = int(self.port.text)
        speed = self.speed.text
        angle = self.angle.text

        s = MyGrid.connecting(h, p)

        var = speed + " " + angle
        s.send(str.encode(str(var)))

        #reply = s.recv(1024)
        #print(reply.decode('utf-8'))
        self.lbl.text = "Speed and angle has been send!"

        s.close()

    def dct(self):
        h = self.ip.text
        p = int(self.port.text)

        s = MyGrid.connecting(h, p)
        s.close()
        self.lbl.text = "Client disconnected!"

    def stop_srvv(self):
        h = self.ip.text
        p = int(self.port.text)

        s = MyGrid.connecting(h, p)

        s.send(str.encode(str("kill ")))

        reply = s.recv(1024)
        print(reply.decode('utf-8'))
        self.lbl.text = "Server stopped!"


class MyApp(App):
    def build(self):
        return MyGrid()


if __name__ == "__main__":
    MyApp().run()

猕猴桃样式部分的代码:

<MyGrid>
    lbl: my_label
    ip: ip
    port: port
    speed: speed
    angle: angle

    GridLayout:
        cols: 1
        size: root.width, root.height

        GridLayout:
            cols: 2
            Label:
                text: "IP"

            TextInput:
                id: ip
                multiline: False

            Label:
                text: "PORT"

            TextInput:
                id: port
                multiline: False

            Label:
                text: "Speed"

            TextInput:
                id: speed
                multiline: False

            Label:
                text: "Angle"

            TextInput:
                id: angle
                multiline: False

        GridLayout:
            cols: 2
            Button:
                text: "CONNECT"
                on_press: root.connecting()

            Button:
                text: "DISCONNECT"
                on_press: root.dct()

        GridLayout:
            cols: 2

            Button:
                text: "SEND DATA"
                on_press: root.send_data()

            Button:
                text: "STOP SERVER"
                on_press: root.stop_srvv()

            Label:
                id: my_label
                text: ""

我想通过TCP连接进行连接,断开连接并发送数据,所有这些都始终使服务器保持活动状态(仅当我按下“停止服务器”按钮时,服务器才应关闭)。 显然,kivy模块具有怪异的结构,我不太了解如何在我的问题和kivy结构中分配多处理。

你们中的某人可以看一下我的代码并通过多处理程序对其进行纠正,以完成我需要的工作,或者至少给我提供建议/教程或其他东西吗?

更新:如您所见,我还没有使用任何多处理代码,首先,我尝试使用pool和map将连接部分划分为一个核心,将其余部分划分为另一个核心,但保持我的服务器还活着,我需要在连接区域中执行一个循环序列。 (我的笔记本电脑只有2个核心)

1 个答案:

答案 0 :(得分:0)

改为使用threading。基本上,多处理就像启动其他整个过程一样,除非您写入文件,否则共享数据并不容易。使用线程,您可以处于同一进程中,并且可以访问线程之间的变量。
这是一个有关如何实现线程化的小例子。

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
import threading

sock = socket.socket()
sock.connect((host, port))


KV = """

BoxLayout:
    Label:
        text: app.label_text

"""

class MyApp(App):
    label_text = StringProperty("")

    def build(self):
        threading.Thread(target=self.update_label).start()
        return Builder.load_string(KV)


    def update_label(self):
        while True:
            self.label_text = sock.recv(1025)


MyApp().run()