【发布时间】:2015-08-17 10:10:22
【问题描述】:
我正在尝试使用 Python 使用 TCP 连接发送和接收数据。我的服务器和客户端在同一个文件中,定义和使用如下。
在构造函数中,我将服务器定义为:
self.sock_in = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock_in.bind((self.host_ip, self.host_port))
self.sock_in.listen(1)
不用担心 host_ip 和 host_port 变量,它们都很好。
在一个函数中,我尝试按如下方式发送数据:
sock_out = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP Connection
sock_out.connect((self.remote_ip, self.remote_port))
sock_out.send(self.navigation_data.get_message())
sock_out.close()
这是我的主要内容:
def main(self):
rospy.logwarn("Starting...")
while not rospy.is_shutdown():
conn = self.sock_in.accept()
try:
recv_buffer = conn.recv(BUFFERSIZE_IN)
if recv_buffer != "":
msg = recv_buffer.decode('utf-8')
msg_type = msg[:msg.find(',')]
if msg_type == self.pilot_control.MESSAGE_ID:
self.pilot_control_handler(msg, self.pilot_control_publisher)
else:
rospy.logwarn("Received an unimplemented message type '%s'", msg_type)
except socket.error as socket_error:
rospy.logerr("SocketError: %s", str(socket_error))
我得到的错误是:
line 230, in send_83b_package
sock_out.connect((self.remote_ip, self.remote_port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 111] Connection refused
我放了一些打印命令来查看它崩溃的地方,显然它没有运行接受命令。直到那里我可以看到打印命令正在工作,但是在接受方法之后没有打印任何内容,这意味着它在那里折叠。
我怀疑问题与同步有关。也就是说,服务器启动速度不够快。
有什么想法吗?
编辑: 其中一个建议是在单独的线程上运行服务器,我尝试如下:
def my_tcp_server(self):
# Establish a TCP Connection
self.sock_in = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock_in.bind((self.host_ip, self.host_port))
self.sock_in.listen(1)
rospy.logwarn("ready")
while not rospy.is_shutdown():
rospy.logwarn("before accept")
conn, address = self.sock_in.accept()
rospy.logwarn("after accept")
try:
recv_buffer = conn.recv(BUFFERSIZE_IN)
rospy.logwarn("recv works!")
if recv_buffer != "":
msg = recv_buffer.decode('utf-8')
msg_type = msg[:msg.find(',')]
if msg_type == self.pilot_control.MESSAGE_ID:
self.pilot_control_handler(msg, self.pilot_control_publisher)
else:
rospy.logwarn("Received an unimplemented message type '%s'", msg_type)
except socket.error as socket_error:
rospy.logerr("SocketError: %s", str(socket_error))
conn.close()
def main(self):
rospy.logwarn("Starting..")
threading.Thread(target=self.my_tcp_server).start()
而在我的构造函数中,调用顺序如下:
self.main()
self.sendDataFunction()
应该没问题。但是,accept 功能仍然不起作用,因此没有连接。
【问题讨论】:
-
你确定它甚至进入了
while块吗?尝试使用pdb单步执行代码。 -
如果您的客户端和服务器在同一个文件中,除非您使用线程/多处理,否则它将无法工作,因为您的 python 脚本一次只能做一件事 - 当它尝试连接,脚本正在连接,即它不能接受,所以连接被拒绝。要修复它,请将服务器代码放在自己的线程中。
-
@Cyphase 是的,它确实进入了 while 块,我在那里打印了一个。虽然它只打印一次,然后它就崩溃了,这意味着接受方法导致了一个阻止程序运行的问题。
-
错误,没有。您必须让客户端和服务器在不同的线程中运行。见stackoverflow.com/questions/8020287/…
-
UDP 是无连接的,所以无线程没有问题。 TCP 要求客户端和服务器同步,因此两端必须同时“运行”python 代码,因此每个端都需要自己的执行线程。请参阅我在之前的评论中找到的示例。请参阅接受的答案以获取一个简单的示例。