2

遠隔操作ロボットのGUIプログラムを拡張しています。アイデアは、同じくPythonで記述されたリモートサーバーに接続するPythonで単純なGUIクライアントをプログラムすることです。クライアントはサーバーに簡単なメッセージを送信し、サーバーはメッセージを受信して​​から、USB経由で接続されているArduinoMegaにシリアル経由で送信します。

コードが機能するようになりました。

現在、クライアントのPython GUIから1回接続し、1つのメッセージを送信すると、接続が失われます。次に、サーバーを停止して再起動し、別の単一のメッセージを送信する必要があります。

ここで何が起きてるの?

これは、別のソースから採用されたサーバースクリプトです。

import serial
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 9000))
sock.listen(1)
print "Listening on TCP 9000"
motor = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
print "Connected to Arduino Mega at: /dev/ttyUSB0"
while(1):
    print "Waiting For Connection..."
    connection, addr = sock.accept()
    connection.setblocking(0)
    print "Connected by", addr[0]
    while(1):
        try:
            sockdata = connection.recv(1)
            break
        except:
            pass
    if sockdata == 'X':
        print "Exiting"
        break
    if sockdata == '0':
        print "Stopping"
        motor.write(sockdata)
    if sockdata == '1':
        print "Forward"
        motor.write(sockdata)
    if sockdata == '2':
        print "Left"
        motor.write(sockdata)
    if sockdata == '3':
        print "Right"
        motor.write(sockdata)
    if sockdata == '4':
        motor.write(sockdata)
        print "Backwards"
    else:
        pass

そして、これが私のクライアントコードから、もちろんリソースファイルを除いたものです。

from socket import *
from PythonCard import model
HOST = ''
PORT = 9000
ADDR = (HOST,PORT)

Client = socket (AF_INET,SOCK_STREAM)
Client.connect((ADDR))

class MainWindow(model.Background):
    def on_FwdBtn_mouseClick(self, event):
        Client.send('1')
    def on_LftBtn_mouseClick(self, event):
        Client.send('2')
    def on_RitBtn_mouseClick(self, event):
        Client.send('3')
    def on_RevBtn_mouseClick(self, event):
        Client.send('4')
    def on_StpBtn_mouseClick(self, event):
        Client.send('0')
    def on_GetPing_mouseClick(self, event):
        Client.send('~')


app = model.Application(MainWindow)
app.MainLoop()

編集

以下の修正または少なくともいくつかの修正を調べた後、サーバーのコードを次に示します。クライアントは同じままです。

import serial
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 9001))
sock.listen(1)
print "Listening on TCP 9001"
motor = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
print "Connected to Motor Controller: /dev/ttyUSB0"
print "Waiting For Connection..."
connection, addr = sock.accept()
connection.setblocking(0)
while(1):

    print "Connected by", addr[0]
    while(1):
        try:
            sockdata = connection.recv(1024)
            break
        except:
            pass
    if sockdata == 'X':
        print "Exiting"
        break
    if sockdata == '0':
        print "Stopping"
        motor.write(sockdata)
    if sockdata == '1':
        print "Forward"
        motor.write(sockdata)
    if sockdata == '2':
        print "Left"
        motor.write(sockdata)
    if sockdata == '3':
        print "Right"
        motor.write(sockdata)
    if sockdata == '4':
        motor.write(sockdata)
        print "Backwards"
    else:
        pass

これは少しうまく機能しますが、それでも正しくないと思います。これを実行すると、サーバーが実行され、GUIを起動した後、サーバー上のターミナルウィンドウを監視して、実際のコマンドを取得できます。

「127.0.0.1から接続」「転送」「127.0.0.1から接続」「左」「127.0.0.1から接続」「右」「127.0.0.1から接続」

コマンドを送信するたびに再接続されるように見えます。GUIを起動した後は接続を維持したいのですが、コマンドを送信するたびに切断して再接続するのではありません。これでちょっとばかげているように聞こえたら申し訳ありませんが、私は約3週間前にPythonを使い始めました。

4

1 に答える 1

3

accept()ループ内で呼び出しているため、別の接続がブロックされます。元の接続は逆参照され、別の接続が着信すると自動的に閉じられます。通常、独立したハンドラー(fork、スレッド、または非同期イベントハンドラーへの追加)を生成して、作業を行う新しい接続を処理します。

于 2011-05-31T02:15:15.660 に答える