一、TCP与UDP
TCP/IP协议族为传输层指明了两个协议:TCP和UDP,它们都是作为应同程序和网络操作的中介物。
**TCP(Transmission Control Protocol)协议全称是传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC793定义。**TCP是面向连接的、可靠的流协议,提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
TCP传输数据稳定可靠,适用于对网络通讯质量要求较高的场景,需要准确无误的传输给对方,比如,传输文件,发送邮件,浏览网页等等。在传输数据前,双方会先建立一条虚拟的通道,可以减少数据传输差错。
传输流程类似下图:
**UDP(User Datagram Protocol)协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。**位于OSI模型中第四层------传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
UDP的优点是速度快,但是可能产生丢包,所以适用于对实时性要求较高但是对少量丢包并没有太大要求的场景。比如:域名查询,语音通话,视频直播等。在数据传输时,每个数据段都是一个独立的信息,包括完整的源地址和目的地,因此,数据能否被对方接收、数据到达的实践和内容的完整性有序性都无法得到保证。
传输流程类似下图:
UDP协议就相当于是写信给对方,寄出去信件之后不能知道对方是否收到信件,信件内容是否完整,也不能得到及时反馈,而TCP协议就像是打电话,你需要知道对方的号码才能打电话,交流的内容可以实时反馈,确保信息的完整性。
两者对比:
TCP | UDP |
---|---|
面向连接 | 面向无连接 |
程序结构较简单 | |
面向字节流 | 基于数据报 |
保证数据顺序 | 不保证数据顺序 |
速度很快 | |
可以检查错误与纠正错误 | 可以检查错误,不可纠正错误 |
总结,UDP更快,更简单,更高效,因此通常用于发送音频和视频文件。TCP是健壮的,可靠的,并保证以相同的顺序传递数据包。
二、ROS的网络通讯方式
ROS提供了两种网络通讯方式,一种是TCP
协议,一种是UDP
协议。默认采用TCP进行通讯,但在实际的wifi网络使用中经常遇到客户端和机器人连接中断且无法重新建立连接的情况。在ROS wiki中官方也有说明,ROSTCP
更适合有线网连接的网络,而ROSUDP
更适合wifi等网络不可靠的无线网络。下面介绍一下如何在ROS中使用UDP连接。
首先,rospy不支持udp连接, 所以要实现ROSUDP必须是用roscpp
写的,然后在订阅的时候添加 ros::TransportHints
指定连接方式。如下面的代码:
cpp
#include <ros/ros.h>
#include <std_msgs/String.h>
void print_message(const std_msgs::String data)
{
ROS_INFO_STREAM("received: " << data);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "udp_test_node");
ros::AsyncSpinner spinner(4);
spinner.start();
ros::NodeHandle private_nh("~");
ros::Subscriber chatter_sub = private_nh.subscribe("/chatter", 10, print_message, ros::TransportHints().unreliable().maxDatagramSize(1000));
while (ros::ok())
{
sleep(1);
}
}
其中 unreliable
用于指定采用udp连接。详细例子可以参照 这个 项目。