TCP和UDP的区别和优缺点及应用场景
一、区别
- TCP 是面向连接的,UDP 是面向无连接的
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
- TCP 保证数据正确性,UDP 可能丢包
- TCP 保证数据顺序,UDP 不保证
- UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
TCP
数据传输慢,UDP
数据传送快
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
- TCP对系统资源要求较多,UDP对系统资源要求较少。
- TCP 是面向字节流的,UDP 是基于数据报的。
二、头部
TCP 20字节 图片
- 状态位。SYN 是发起一个链接,ACK 是回复,RST 是重新连接,FIN 是结束连接。因为 TCP 是面向连接的,因此需要双方维护连接的状态,这些状态位的包会引起双方的状态变更
- 窗口大小,TCP 要做流量控制,需要通信双方各声明一个窗口,标识自己当前的处理能力。
UDP头部 8字节
三、网络编程
1. TCP
TCP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket(); SOCKET SocketListen =socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
2、设置socket属性,用函数setsockopt(); * 可选
3、绑定IP地址、端口等信息到socket上,用函数bind(); SOCKET_ERROR = bind(SocketListen,(const sockaddr*)&addr,sizeof(addr))
4、开启监听,用函数listen(); SOCKET_ERROR == listen(SocketListen,2)
5、接收客户端上来的连接,用函数accept(); SOCKET SocketWaiter = accept(SocketListen, _Out_ struct sockaddr *addr _Inout_ int *addrlen);
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接; closesocket(SocketListen);closesocket(SocketWaiter);
8、关闭监听;
TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
int send( _In_ SOCKET s, //向哪个socket发送,accept返回的socket。 _In_ const char *buf, _In_ int len, _In_ int flags ); send(SocketClient,(const char *)&fh,sizeof(fh),0); recv(SocketClient,szbuf,sizeof(szbuf),0);
2. UDP
与之对应的UDP编程步骤要简单许多,分别如下:
UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;
UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;
int recvfrom( _In_ SOCKET s, //绑定的socket _Out_ char *buf, _In_ int len, _In_ int flags, _Out_ struct sockaddr *from, //用来接收对方的 _Inout_opt_ int *fromlen ); int nres=recvfrom(pThis->m_socketListen,szBuf,sizeof(szBuf),0,(sockaddr*)&addrClient,&nSize);//0处标志位 sendto(m_socketListen,szBuffer,nSize,0,(const sockaddr*)&addr,sizeof(sockaddr_in))
注意区分recvfrom函数,由于是UDP非连接的所以在接受数据是要接受对方的ip等信息用于稍后发送信息,而TCP使用已连接的套接字维护连接信息。
SOCK_STREAM这种的特点是面向连接的,即每次收发数据之前必须通过connect建立连接,而SOCK_DGRAM这种是User Datagram Protocol协议的网络通讯,它是无连接的,不可靠的。
两者都是是OSI模型中传输层的协议
四、应用场景
UDP 的主要应用场景
- 需要资源少,网络情况稳定的内网,或者对于丢包不敏感的应用,比如 DHCP 就是基于 UDP 协议的。
- 不需要一对一沟通,建立连接,而是可以广播的应用。因为它不面向连接,所以可以做到一对多,承担广播或者多播的协议。
- 需要处理速度快,可以容忍丢包,但是即使网络拥塞,也毫不退缩,一往无前的时候
基于 UDP 的几个例子
- 直播。直播对实时性的要求比较高,宁可丢包,也不要卡顿的,所以很多直播应用都基于 UDP 实现了自己的视频传输协议
- 实时游戏。游戏的特点也是实时性比较高,在这种情况下,采用自定义的可靠的 UDP 协议,自定义重传策略,能够把产生的延迟降到最低,减少网络问题对游戏造成的影响
- 物联网。一方面,物联网领域中断资源少,很可能知识个很小的嵌入式系统,而维护 TCP 协议的代价太大了;另一方面,物联网对实时性的要求也特别高。比如 Google 旗下的 Nest 简历 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的
- 许多应用只支持UDP,如:多媒体数据流,不产生任何额外的数据,即使知道有破坏的包也不进行重发。
- 视频聊天
TCP 的主要应用场景
- 适用于对数据传输可靠性要求比较高的场景,例如文本传输。
- 互联网和企业网上客户端应用,数据传输性能让位于数据传输的完整性,可控制性和可靠性。
- 发消息的场景以及文件传输,要确保发送的消息不丢失
总结:
很明显,当数据传输的性能必须让位于数据传输的完整性、可控制性和可靠性时,TCP协议是当然的选择。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择,如:DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时,UDP较低的开销使其有更好的机会去传送管理数据。TCP丰富的功能有时会导致不可预料的性能低下,但是我们相信在不远的将来,TCP可靠的点对点连接将会用于绝大多数的网络应用。
五、对应的协议
TCP
对应的协议
FTP:
定义了文件传输协议,使用21端口。Telnet:
一种用于远程登陆的端口,使用23端口,用户可以以自己的身份远程连接到计算机上,可提供基于DOS模式下的通信服务。SMTP:
邮件传送协议,用于发送邮件。服务器开放的是25号端口。POP3:
它是和SMTP对应,POP3用于接收邮件。POP3协议所用的是110端口。HTTP:
是从Web服务器传输超文本到本地浏览器的传送协议。
UDP
对应的协议
DNS:
用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。SNMP:
简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。TFTP(Trival File Transfer Protocal)
,简单文件传输协议,该协议在熟知端口69上使用UDP
服务。