1、简介UDP
????????UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768?是UDP的正式规范。UDP在IP报文的协议号是17。
????????UDP是OSI参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成?[4]??,提供面向事务的简单不可靠信息传送服务。UDP 协议基本上是IP协议与上层协议的接口。UDP协议适用端口分别运行在同一台设备上的多个应用程序。
????????UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。常用的UDP端口号有:53(DNS)、69(TFTP)、161(SNMP),使用UDP协议包括:TFTP、SNMP、NFS、DNS、BOOTP。
????????UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
2、问题描述
? ? ? ? 使用UDP协议在两台设备之间进行数据信息通信,下位机接收上位机指令,将数据传输到上位机;一旦上位机发送的数据下位机没有接收到,UDP线程就会阻塞导致上位机无法与下位机进行数据通信。解决方案一般有两种:第一种将线程退出重新创建线程,第二种将开发板重启。上述两种解决方案在实际的项目应用中都是最差方案,最佳解决方案应该是:当接收数据线程在一定时间内未接收到数据就自动退出,并且返回错误代码。
3、解决方案
? ? ? ? 首先,查询LWIP网络协议得知,在创建socket时可以对socket的相关参数进行配置,例如超时接收参数,以及超时发送参数等。在rtthread当中有setsocketopt函数定义;
?
?然后,具体的使用如下:
struct timeval tv_out;
tv_out.tv_sec = 3; //超时时间单位是s
tv_out.tv_usec = 0; //超时时间单位是us
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out)); /*设置超时时间*/
? ? ? ? 第一行是定义一个timeval结构体,用于设置超时时间?;第四行是将超时时间作为setsocket的option。上面这段代码最终的执行效果是:当客户端未接收到服务器的数据时会等待5s,若是5s之内仍未接收到数据,就结束recvfrom函数,UDP线程继续运行。
4、总结
? ? ? ? 在需要超时接收的实际应用场景中,上述解决方案为最佳方案,前两种方案只有在实验阶段有效。又成功水了一篇,文中若是有讲的不准确的地方,欢迎大家在评论区留言。最后,博主是个又菜又爱玩的人!!!
?
|