TCP与UDP(非常详细)

tcp 类似打电话,udp类似写信


前言

TCP/IP模型是一些列协议的总称(TCP,UDP,IP,FTP,HTTP,ICMP,SMTP)。这些协议可以划分为四层:链路层、网络层、传输层、应用层。
TCP和UDP都位于计算机网络模型中的传输层,它们主要负责传输应用层产生的数据。。


TCP\UDP

UDP和TCP 在使用TCP/IP 体系结构的网络通信中,这两个协议的使用频率仅次于网际层的IP协议。TCP/IP 体系结构应用层中的某些协议需要使用运输层的TCP 提供的服务,而另一些协议需要使用运输层的UDP 提供的服务,UDP 是用户数据报协议的英文缩写词,TCP 是传输控制协议的英文缩写词。

TCP

TCP(Transmission Control Protocol 传输控制协议):一种面向连接的、可靠的、基于字节流的传输层通信协议,使用三次握手协议建立连接、四次挥手断开连接。面向连接意味着两个使用TCP的应用(通常是一个客户端和一个服务器)在彼此交换数据包之前必须先建立一个TCP连接。在一个TCP连接中,仅有两方进行彼此通信,广播和多播不能用TCP。TCP 协议的作用是,保证数据通信的完整性和可靠性,防止丢包。TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种端点我们叫作套接字(socket),端口号拼接到IP地址即构成了套接字。

UDP

UDP(User Datagram Protocol 用户数据报协议):是OSI(Open System Interconnection 开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。

区别

  1. TCP面向连接,UDP面向无连接

UDP是不需要和TCP一样建立三次握手连接的。而TCP则在通信前是需要进行三次握手的。
两台主机如果在运输层使用UDP协议进行通信,双方可以随时发送数据,
再来看使用TCP 协议的情况,使用TCP协议的通信,双方在进行数据传输之前必须使用三报文握手来建立TCP 连接。TCP 连接建立成功后才能进行数据传输,数据传输结束后必须使用四报文挥手来释放TCP连接。需要注意的是这里所谓的连接是指逻辑连接关系,而不是物理连接。

  1. TCP是可靠的,UDP是不可靠的

TCP保证数据的正确性以及顺序,UDP不保证还可能丢包。
UDP只会把想发的数据报文一股脑的丢给对方,并不在意数据有无安全完整到达。
在TCP协议中使用了接收确认和重传机制,使得每一个信息都能保证到达,是可靠的。
而UDP是尽力传送,没有应答和重传机制,UDP只是将信息发送出去,对方收不收到也不进行应答。所以UDP协议是不可靠的。

  1. TCP/UDP传输方式

UDP 不仅支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
TCP不能一对多的原因是:TCP通信前要跟一台主机进行三次握手连接,因此TCP不能对多,只能一对一。

  1. TCP是面向字节流的,UDP是面向报文的

TCP基于流的传输表示TCP不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息),这正是TCP 实现可靠传输、流量控制以及控制的基础.
UDP面向报文,是有 保护消息边界 的,接收方一次只能接受一条独立的消息,所以UDP不存在粘包。

  1. TCP的头部开销大,UDP的头部开销小

UDP的头部很小,只有8个字节。TCP的头部至少要20个字节

  1. TCP会产生粘包问题,UDP会产生丢包问题

TCP产生粘包问题的主要原因是:TCP是面向连接的,所以在TCP看来,并没有把消息看成一条条的,而是全部消息在TCP眼里都是字节流,因此容易把多个消息混在一起后,TCP就分不清了
UDP是没有应答和重传机制,因此包很容易传丢了而且自己都不知道
主要丢包原因: 1、接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv。 2、发送的包巨大丢包:虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行。例如超过50K的一个udp包,不切割直接通过send方法发送也会导致这个包丢失。这种情况需要切割成小包再逐个send。 3、发送的包较大,超过接受者缓存导致丢包:包超过mtu size(mtu表示最大传输单元)数倍,几个大的udp包可能会超过接收者的缓冲,导致丢包。这种情况可以设置socket接收缓冲。以前遇到过这种问题,我把接收缓冲设置成64K就解决了。 4、发送的包频率太快:虽然每个包的大小都小于mtu size 但是频率太快,例如40多个mut size的包连续发送中间不sleep,也有可能导致丢包。

总结

TCP与UDP区别总结:
1、TCP传输效率慢、所需资源多,UDP则相反。
2、TCP面向连接(打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
3、TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
4、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
5、UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
6、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
7、TCP首部开销20字节;UDP的首部开销小,只有8个字节
8、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
9、TCP适用要求可靠传输的应用(文件传输),UDP适用实时应用(直播、视频会议、IP电话)

扩展

1、为什么tcp是三次握手不是两次握手:防止已失效的请求报文(客服端给服务端发送的SYN包由于某些原因没有到达服务器,在中间某个网络节点滞留,这时客户端会重新发送SYN包),突然又传到服务器引起错误。这时候服务端以为是两个连接,而客户端以为一个连接.

udp的使用

#include<winsock2.h>
#include<vector>
#include<WS2tcpip.h>
#include<string>
#pragma comment(lib,"ws2_32.lib")
void CTestsqlite3Dlg::OnBnClickedButtonUdp()
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		printf("初始化winsock失败.\n");
		return;
	}
	SOCKET sock = ::socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
	{
		printf("无法创建套接字.\n");
		WSACleanup();
		return;
	}
	sockaddr_in serverAddr;
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(8080);  // 设置目标端口号
	//serverAddr.sin_addr.s_addr = inet_addr("192.168.1.100");  // 设置目标IP地址
	inet_pton(AF_INET, "192.168.74.1", &(serverAddr.sin_addr)); // 设置目标IP地址

	//要发送的数据
	std::string sAllData = "UDP的测试";

	std::vector<char> buffer(sAllData.begin(), sAllData.end());
	const char* data = buffer.data();
	int dataSize = strlen(data);
	int bytesSent = sendto(sock, data, dataSize, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
	if (bytesSent == SOCKET_ERROR)
	{
		printf("发送数据失败.\n");
		closesocket(sock);
		WSACleanup();
		return;
	}
	closesocket(sock);
	WSACleanup();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Minuw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值