【发布时间】:2020-06-01 09:42:18
【问题描述】:
大家好,我想实现一个 python ros 节点,它订阅一个主题(在我的例子中是 odom)并在套接字上重新传输部分消息。我已经实现了这样的事情:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
import socket
import sys
from nav_msgs.msg import Odometry
import struct
from time import sleep
import socket, threading
class ClientThread(threading.Thread):
def __init__(self,clientAddress,clientsocket):
threading.Thread.__init__(self)
self.csocket = clientsocket
print ("New connection added: ", clientAddress)
rospy.init_node('serverOdom', anonymous=True)
rospy.Subscriber('odom',Odometry, callback)
print ("New subscriber 'severOdom' added: ")
def run(self):
rospy.spin()
def callback(msg):
string=str(msg.pose.pose.position.x)+"\n"+str(msg.pose.pose.position.y)+"\n"
try:
##How i can refeer to the socket??
self.csocket.send(string.encode())
print (string)
except socket.error:
print ("Error client lost")
##How to exit from spin()??
if __name__ == '__main__':
LOCALHOST = "192.168.2.150"
PORT = 5005
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((LOCALHOST, PORT))
print("Server started")
print("Waiting for client request..")
while True:
server.listen(1)
clientsock, clientAddress = server.accept()
newthread = ClientThread(clientAddress, clientsock)
newthread.start()
现在我有两个问题: 第一个在回调函数里面我不能用的
self.csocket.send(string.encode())
我不知道如何将字符串发送给客户端。
第二个是如果客户端断开连接我无法退出回调函数
有什么想法吗?我是python和ros的初学者,提前谢谢
编辑: 我建立了一个解决方案。也许它并不优雅,但它确实有效。
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
import socket
import sys
from nav_msgs.msg import Odometry
import struct
from time import sleep
import socket, threading
class ClientThread(threading.Thread):
def __init__(self,clientAddress,clientsocket):
threading.Thread.__init__(self)
self.csocket = clientsocket
print ("New connection added: ", clientAddress)
rospy.init_node('serverOdom', anonymous=True)
rospy.Subscriber('odom',Odometry, callback)
print ("New subscriber 'severOdom' added: ")
def run(self):
while True:
msg = rospy.wait_for_message("odom", Odometry, timeout=None)
string=str(msg.pose.pose.position.x)+"\n"+str(msg.pose.pose.position.y)+"\n"
try:
self.csocket.send(string.encode())
except socket.error:
print ("Error client lost", clientAddress)
return
def callback(msg):
pass
if __name__ == '__main__':
LOCALHOST = ""
PORT = 5005
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((LOCALHOST, PORT))
print("Server started")
print("Waiting for client request..")
while True:
sleep(2)
server.listen(5)
clientsock, clientAddress = server.accept()
newthread = ClientThread(clientAddress, clientsock)
newthread.start()
我需要更多的客户端来连接,当与客户端的连接丢失(例如因为客户端关闭)时,服务器创建的线程结束。 使用我为服务器创建的每个线程的解决方案还创建了一个订阅者,可能最好为所有创建的线程使用单个订阅者,但现在我还不能这样做。
【问题讨论】: