Python套接字服务器和客户端,不断失去连接

发布于 2024-11-11 21:29:53 字数 3493 浏览 0 评论 0原文

我正在扩展远程控制机器人的 GUI 程序。这个想法是用 Python 编写一个简单的 GUI 客户端,连接到同样用 Python 编写的远程服务器。客户端将简单的消息发送到服务器,服务器将接收消息,然后通过串行将其传输到 通过 USB 连接的 Arduino Mega

我已经让代码可以工作了。

现在,我可以从客户端 Python GUI 连接一次,发送一条消息,然后就失去连接。然后我必须停止服务器,重新启动它,然后发送另一条消息。

这里发生了什么?

这是从另一个来源采用的服务器脚本。

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 后保持连接,而不是每次发送命令时断开连接并重新连接。 抱歉,如果我在这方面听起来有点愚蠢,但我大约三周前才开始使用 Python。

I am expanding on a GUI program for a remotely controlled robot. The idea is to program a simple GUI client in Python that connects to a remote server, also written in Python. The client would send simple messages to the server, the server would receive the message, and then transmit it via serial to an Arduino Mega that is connected via USB.

I have gotten the code to work, kind of.

Right now, I can connect one time from my client Python GUI, send one message, then it loses connection. Then I must halt the server, restart it, and then send another single message.

What is happening here?

Here is the server script, adopted from another source.

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

And here is my client code, minus the resource file of course.

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

EDIT

After looking into the below fixes or at least some of them, here is my code for the server now, the client remains the same.

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

This works a little better, but still not right I don't think. When I run this I get the server running, and after starting my GUI, I can watch my terminal window on the server and will get the actual commands as they come through

"Connected from 127.0.0.1" "Forward"
"Connected from 127.0.0.1" "left"
"Connected from 127.0.0.1" "right"
"Connected from 127.0.0.1"

It looks as though each time I send a command I get reconnected. I want to maintain a connection once I start my GUI, not disconnect and reconnect each time I send a command.
Sorry if I sound kind of stupid in this, but I just started with Python about three weeks ago.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原野 2024-11-18 21:29:53

您在循环内调用 accept(),这将阻止另一个连接。当/如果另一个连接进入时,原始连接将被取消引用并自动关闭。通常,您会生成一个独立的处理程序(fork、线程或添加到异步事件处理程序)来处理完成工作的新连接。

You are calling accept() inside the loop, which will block for another connection. The original connection will be dereferenced and automatically closed when/if another connection comes in. Normally, you spawn an independent handler (fork, thread, or add to async event handler) to handle new connections that does the work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文