1. 什么是网络
1.1 网络的定义
网络(Network)是由若干节点和连接这些节点的链路构成的图,表示诸多对象及其相互联系。网络有资源共享、快速传输信息、提高系统可靠性、易于进行分布式处理和综合信息服务等特性。
1.2 网络的实质
网络就是多个主机连接到一起, 各个主机之间可以传输信息, 资源共享等功能。
1.3 主机的类型
主机可以是交换机,基站,路由器,电脑,手机等等
1.4 信息的传递
基站与基站之间通过无线电进行信息的传递。或者其它主机之间通过光,电等物理媒介进行信息的传递。
2. 网络分层
2.1 五层模型
- 应用层
- 传输层
- 网络层
- 数据链路层
- 物理层
2.2 七层模型(OSI Open System Interconnection)
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
2.3 每层作用以及相关协议
应用层:为操作系统或网络应用程序提供访问网络服务的接口,常见的协议有 FTP HTTP HTTPS SMTP DNS等。
表示层:提供数据格式转换服务,解密与加密,图片的解码与编码,数据的压缩和解压缩,常见协议有 URL加密 口令加密 图片编解码等等。
会话层:建立端连接并提供访问验证和会话管理,例如使用效验点可使会话在通信失效时从效验点恢复通信。常见:服务器验证用户登录,断点续传。
传输层:提供应用进程之间的逻辑通信,建立连接,处理数据包错误,处理数据包次序,常见协议:TCP UDP SPX
网络层:为数据在结点之间传输创建逻辑链路,并分组转发数据。例如,对子网间的数据包进行路由选择,常见的有路由器,多层交换机,防火墙,IP,IPX,RIP,OSPF。
数据链路层:在通信实体建立数据链路连接。例如,将数据分帧并处理流控制,物理地址寻址,重发等。常见的有网卡,网桥,二层交换机。
物理层:为数据端设备提供原始比特流的传输通路。例如,网络通信的数据传输介质由电缆与设备共同构成。常见的有中继器,集线器,网线,HUB等。
3. ip, 网关,子网掩码,端口
3.1 ip(Internet Protocol)
网络之间互连的协议,也就是为计算机网络相互连接进行通信而设计的协议,IP协议也可以叫做因特网协议。ip用来区分网络中的不同主机,例如ipv4的本质就是一个4字节(byte)的无符号(unsigned)整数。
例如: 192.168.1.123 数点格式字符串
3.2 网关
网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。
3.3 子网掩码
子网掩码前三段确定路由,最后一段确定主机,子网掩码为(255.255.255.0),使用子网掩码&ip地址可以得到IP地址的前三段,使用(~子网掩码)&ip可以得到IP地址的最后一段。
3.4 端口
在同一个主机之上有多个端口,每个进程使用唯一的一个端口,例如浏览器使用 80 号端口,一般端口都是从小到大使用的,个人写的应用程序一般建议使用5000以上的端口号,一般计算机有 0 --- 65535 共计 65536 个端口,因此建议使用10000左右的端口比较稳妥。
4. 传输层协议之TCP通信
4.1 TCP通信编程模型
服务器(server) | 客户端(client) |
1. 创建socket | 1. 创建socket |
2. 确定服务器协议地址簇 | 2. 获取服务器协议地址簇 |
3. 绑定 | |
4. 监听 | |
5. 接受连接 | 3. 连接服务器 |
6. 通信 | 4. 通信 |
7. 断开连接 | 5. 断开连接 |
4.2 TCP实现简单通信
4.2.1 Server端
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <string.h>
-
#include <signal.h>
-
int serverSocket,clientSocket;
-
void hand(int val){
-
//7. 关闭连接
-
close(serverSocket);
-
close(clientSocket);
-
printf("bye bye!\n");
-
exit(0);
-
}
-
int main(int argc,char* argv[]){
-
if(argc != 3) printf("请输入ip地址和端口号!\n"),exit(0);
-
printf("ip: %s port:%d\n",argv[1],atoi(argv[2]));
-
signal(SIGINT,hand);
-
//1. 创建socket 参数一: 协议类型(版本) 参数二: 通信媒介 参数三: 保护方式
-
serverSocket = socket(AF_INET,SOCK_STREAM,0);
-
if(-1 == serverSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in sAddr = { 0 };
-
sAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
-
sAddr.sin_addr.s_addr = inet_addr(argv[1]); //将字符串转整数
-
sAddr.sin_port = htons(atoi(argv[2])); //将字符串转整数,再将小端转换成大端
-
//3. 绑定服务器协议地址簇
-
int r = bind(serverSocket,(struct sockaddr*)&sAddr,sizeof sAddr);
-
if(-1 == r) printf("绑定失败:%m\n"),close(serverSocket),exit(-2);
-
printf("绑定成功!\n");
-
//4. 监听
-
r = listen(serverSocket,10);
-
if(-1 == r) printf("监听失败:%m\n"),close(serverSocket),exit(-3);
-
printf("监听成功!\n");
-
//5. 接收客户端连接
-
struct sockaddr_in cAddr = {0};
-
int len = sizeof(sAddr);
-
clientSocket = accept(serverSocket,(struct sockaddr*)&cAddr,&len);
-
if(-1 == clientSocket) printf("接收客户端连接失败:%m\n"),close(serverSocket),exit(-1);
-
printf("有客户端连接上服务器了: %s\n",inet_ntoa(cAddr.sin_addr));
-
//6. 通信
-
char buff[256] = {0};
-
while(1){
-
r = recv(clientSocket,buff,255,0);
-
if(r > 0){
-
buff[r] = 0;
-
printf("客户端说>> %s\n",buff);
-
}
-
}
-
return 0;
-
}
4.2.2 Client端
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <string.h>
-
#include <signal.h>
-
int clientSocket;
-
void hand(int val){
-
//5. 关闭连接
-
close(clientSocket);
-
printf("bye bye!\n");
-
exit(0);
-
}
-
int main(int argc,char* argv[]){
-
if(argc != 3) printf("请输入ip地址和端口号!\n"),exit(0);
-
printf("ip: %s port:%d\n",argv[1],atoi(argv[2]));
-
signal(SIGINT,hand);
-
//1. 创建socket 参数一: 协议类型(版本) 参数二: 通信媒介 参数三: 保护方式
-
clientSocket = socket(AF_INET,SOCK_STREAM,0);
-
if(-1 == clientSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in cAddr = { 0 };
-
cAddr.sin_family = AF_INET;
-
cAddr.sin_addr.s_addr = inet_addr(argv[1]); //将字符串转整数
-
cAddr.sin_port = htons(atoi(argv[2])); //将字符串转整数,再将小端转换成大端
-
//3.连接服务器
-
int r = connect(clientSocket,(struct sockaddr*)&cAddr,sizeof cAddr);
-
if(-1 == r) printf("连接服务器失败:%m\n"),close(clientSocket),exit(-2);
-
printf("连接服务器成功!\n");
-
//4. 通信
-
char buff[256] = {0};
-
while(1){
-
printf("你想要发送:");
-
scanf("%s",buff);
-
send(clientSocket,buff,strlen(buff),0);
-
}
-
return 0;
-
}
4.3 TCP实现文件传输
4.3.1 实现连接后,文件传输步骤
接收端(Server) | 发送端(Client) |
1. 等待客户端发送 | 1. 发送文件名 |
2. 接收文件名并创建文件 | 2. 获取文件大小并发送 |
3. 接收文件大小并打开文件 | 3. 打开文件准备读取发送 |
4. 循环接收并写入文件 | 4. 循环读取文件并发送文件内容 |
5. 写入数据完毕,关闭文件和连接 | 5. 发送数据完毕,关闭文件和连接 |
4.3.2 server(接收文件)端
-
//Server端
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <fcntl.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
int serverSocket,clientSocket;
-
int main(){
-
//1. 创建socket
-
serverSocket = socket(AF_INET,SOCK_STREAM,0);
-
if(-1 == serverSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in sAddr = {0};
-
sAddr.sin_family = AF_INET;
-
sAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
sAddr.sin_port = htons(9527);
-
//3.绑定
-
int r = bind(serverSocket,(struct sockaddr*)&sAddr,sizeof sAddr);
-
if(-1 == r) printf("绑定失败:%m\n"),close(serverSocket),exit(-2);
-
printf("绑定成功!\n");
-
//4.监听
-
r = listen(serverSocket,10);
-
if(-1 == r) printf("监听失败:%m\n"),close(serverSocket),exit(-2);
-
printf("监听成功!\n");
-
//5.等待客户端连接
-
struct sockaddr_in cAddr = {0};
-
int len = sizeof(cAddr);
-
clientSocket = accept(serverSocket,
-
(struct sockaddr*)&cAddr,&len);
-
if(-1 == clientSocket) printf("服务器崩溃:%m\n"),close(serverSocket),exit(-3);
-
printf("有客户端连接上服务器了:%s\n",inet_ntoa(cAddr.sin_addr));
-
//6. 通信
-
char fileName[256] = {0};
-
int fileSize = 0;
-
char buff[1024] = {0};
-
int fileCount; //统计写入文件内容的大小
-
sleep(2);
-
//6.1 接收文件名
-
r = recv(clientSocket,fileName,255,0);
-
if(r > 0){
-
printf(">>>>>>%d\n",r);
-
printf("接收到的文件名为: %s\n",fileName);
-
}
-
sleep(2);
-
//6.2 接收文件大小
-
r = recv(clientSocket,(int*)&fileSize,4,0);
-
if(r == 4){
-
printf("文件大小r>>> %d\n",r);
-
printf("接收到的文件大小为: %d\n",fileSize);
-
}
-
//6.3 创建文件
-
int fd = open(fileName,O_CREAT | O_WRONLY,0666);
-
if(-1 == fd) printf("创建文件失败:%m\n"),
-
close(serverSocket),close(clientSocket),exit(-4);
-
sleep(2);
-
//6.4 接收信息并写入文件
-
while(1){
-
r = recv(clientSocket,buff,1024,0);
-
if(r > 0){
-
write(fd,buff,r);
-
fileCount += r;
-
if(fileCount >= fileSize)
-
break;
-
}
-
}
-
//7. 关闭文件以及关闭连接
-
sleep(1);
-
close(fd);
-
close(serverSocket);
-
close(clientSocket);
-
printf("文件接收完毕!\n");
-
return 0;
-
}
注: accept函数为阻塞函数
4.3.3 client(发送文件)端
-
//Client端
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <fcntl.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <sys/stat.h>
-
int clientSocket;
-
int main(int argc,char* argv[]){
-
//1. 创建socket
-
clientSocket = socket(AF_INET,SOCK_STREAM,0);
-
if(-1 == clientSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in cAddr = {0};
-
cAddr.sin_family = AF_INET;
-
cAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
cAddr.sin_port = htons(9527);
-
//3.连接服务器
-
int r = connect(clientSocket,(struct sockaddr*)&cAddr,sizeof cAddr);
-
if(-1 == r) printf("连接服务器失败:%m\n"),close(clientSocket),exit(-2);
-
printf("连接服务器成功!\n");
-
//4. 通信
-
//4.1 打开文件
-
int fd = open(argv[1],O_RDONLY,0666);
-
if(-1 == fd) printf("文件打开失败:%m\n"),close(clientSocket),exit(-3);
-
printf("文件打开成功!\n");
-
//4.1 获取文件大小
-
struct stat st = {0};
-
stat(argv[1],&st);
-
printf("文件大小为: %d\n",(int)st.st_size);
-
printf("文件名为:%s\n",argv[1]);
-
sleep(2);
-
//4.2 将文件名和文件大小发送给服务器(注意先后顺序)
-
send(clientSocket,argv[1],strlen(argv[1]),0);
-
sleep(2);
-
send(clientSocket,(char*)&st.st_size,4,0);
-
//4.3 读取内容并发送
-
sleep(2);
-
char buff[1024] = {0};
-
while(1){
-
r = read(fd,buff,1024);
-
if(r > 0)
-
send(clientSocket,buff,r,0);
-
else
-
break;
-
}
-
//5. 关闭文件
-
sleep(1);
-
close(fd);
-
close(clientSocket);
-
printf("文件发送完毕!\n");
-
return 0;
-
}
5. 传输层协议之UDP通信
5.1 UDP通信编程模型
服务器(Server) | 客户端(Client) |
1. 创建Socket | 1. 创建Socket |
2. 确定服务器协议地址簇 | 2. 获取服务器协议地址簇 |
3. 绑定 | |
4. 通信 | 3. 通信 |
5.2 UDP实现简单通信
5.2.1 Server端
-
//Server
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <signal.h>
-
int serverSocket;
-
void hand(int val){
-
//5. 关闭serverSocket
-
close(serverSocket);
-
printf("bye bye!\n");
-
exit(0);
-
}
-
int main(int argc,char* argv[]){
-
if(argc != 3) printf("请输入ip地址和端口号!\n"),exit(0);
-
printf("ip:%s port:%d\n",argv[1],atoi(argv[2]));
-
signal(SIGINT,hand);
-
//1. 创建socket 参数一: 协议类型(版本) 参数二: 通信媒介 参数三: 保护方式
-
serverSocket = socket(AF_INET,SOCK_DGRAM,0);
-
if(-1 == serverSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in sAddr = {0};
-
sAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
-
sAddr.sin_addr.s_addr = inet_addr(argv[1]); //将字符串转整数
-
sAddr.sin_port = htons(atoi(argv[2])); //整数转整数 小端转大端
-
//3.绑定
-
int r = bind(serverSocket,(struct sockaddr*)&sAddr,sizeof sAddr);
-
if(-1 == r) printf("绑定失败:%m\n"),close(serverSocket),exit(-2);
-
printf("绑定成功!\n");
-
//4.通信
-
char buff[256];
-
struct sockaddr_in cAddr = {0};
-
int len = sizeof(cAddr);
-
while(1){
-
//如果还需要向客户端发送东西用recvfrom
-
//udp精髓 向一个协议地址簇发东西
-
//收消息
-
r = recvfrom(serverSocket,buff,255,0,(struct sockaddr*)&cAddr,&len);
-
if(r > 0){
-
buff[r] = 0; //添加字符串结束符号
-
printf(">> %s\n",buff);
-
}
-
printf("你想对客户端说什么: ");
-
memset(buff,256,0);
-
scanf("%s",buff);
-
sendto(serverSocket,buff,strlen(buff),0,
-
(struct sockaddr*)&cAddr,sizeof cAddr);
-
}
-
return 0;
-
}
5.2.2 Client端
-
//Client
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <signal.h>
-
int clientSocket;
-
void hand(int val){
-
//4. 结束
-
close(clientSocket);
-
printf("bye bye!\n");
-
exit(0);
-
}
-
int main(int argc,char* argv[]){
-
if(argc != 3) printf("请输入ip地址和端口号!\n"),exit(0);
-
printf("ip:%s port:%d\n",argv[1],atoi(argv[2]));
-
signal(SIGINT,hand);
-
//1. 创建socket 参数一: 协议类型(版本) 参数二: 通信媒介 参数三: 保护方式
-
clientSocket = socket(AF_INET,SOCK_DGRAM,0);
-
if(-1 == clientSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in cAddr = {0};
-
cAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
-
cAddr.sin_addr.s_addr = inet_addr(argv[1]); //将字符串转整数
-
cAddr.sin_port = htons(atoi(argv[2])); //整数转整数 小端转大端
-
//3.通信
-
char buff[256];
-
char temp[256];
-
int r;
-
int len = sizeof cAddr;
-
while(1){
-
//发消息
-
printf("你想发送什么: ");
-
scanf("%s",buff);
-
sendto(clientSocket,buff,strlen(buff),0,
-
(struct sockaddr*)&cAddr,len);
-
//收消息
-
r = recvfrom(clientSocket,temp,255,0,
-
(struct sockaddr*)&cAddr,&len);
-
if(r > 0){
-
temp[r] = 0;
-
printf("服务器发来信息>> %s\n",temp);
-
}
-
}
-
return 0;
-
}
这样就实现了傻瓜式的一应一答的双向通信
5.3 UDP实现文件传输
5.3.1 Server(文件接收)端
-
//Server端(文件接收)
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <fcntl.h>
-
int serverSocket;
-
int main(){
-
//1. 创建socket
-
serverSocket = socket(AF_INET,SOCK_DGRAM,0);
-
if(-1 == serverSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in sAddr = {0};
-
sAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
-
sAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //将字符串转整数
-
sAddr.sin_port = htons(9527);
-
//3.绑定
-
int r = bind(serverSocket,(struct sockaddr*)&sAddr,sizeof sAddr);
-
if(-1 == r) printf("绑定失败:%m\n"),close(serverSocket),exit(-2);
-
printf("绑定成功!\n");
-
//4.通信(实现文件传输)
-
struct sockaddr_in cAddr = {0};
-
char fileName[256] = {0};
-
int fileSize = 0;
-
char buff[1024] = {0};
-
int fileCount; //统计写入文件内容的大小
-
int len = sizeof(cAddr);
-
sleep(2);
-
//4.1 接收文件名
-
r = recvfrom(serverSocket,fileName,255,0,
-
(struct sockaddr*)&cAddr,&len);
-
if(r > 0){
-
printf(">>>>>>%d\n",r);
-
printf("接收到的文件名为: %s\n",fileName);
-
}
-
sleep(2);
-
//4.2 接收文件大小
-
r = recvfrom(serverSocket,(int*)&fileSize,4,0,
-
(struct sockaddr*)&cAddr,&len);
-
if(r == 4){
-
printf("文件大小r>>> %d\n",r);
-
printf("接收到的文件大小为: %d\n",fileSize);
-
}
-
//4.3 创建文件
-
int fd = open(fileName,O_CREAT | O_WRONLY,0666);
-
if(-1 == fd) printf("创建文件失败:%m\n"),
-
close(serverSocket),exit(-4);
-
sleep(2);
-
//4.4 接收信息并写入文件
-
while(1){
-
r = recvfrom(serverSocket,buff,1024,0,
-
(struct sockaddr*)&cAddr,&len);
-
if(r > 0){
-
write(fd,buff,r);
-
fileCount += r;
-
if(fileCount >= fileSize)
-
break;
-
}
-
}
-
//5. 关闭serverSocket
-
sleep(1);
-
close(fd);
-
close(serverSocket);
-
printf("bye bye!\n");
-
return 0;
-
}
5.3.2 Client(文件发送)端
-
//Client端(文件发送)
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <fcntl.h>
-
#include <sys/stat.h>
-
int clientSocket;
-
int main(int argc,char* argv[]){
-
//1. 创建socket
-
clientSocket = socket(AF_INET,SOCK_DGRAM,0);
-
if(-1 == clientSocket) printf("创建socket失败:%m\n"),exit(-1);
-
printf("创建socket成功!\n");
-
//2. 创建服务器协议地址簇
-
struct sockaddr_in cAddr = {0};
-
cAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
-
cAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //将字符串转整数
-
cAddr.sin_port = htons(9527); //小端转大端
-
//3.通信(文件发送)
-
//3.1 打开文件
-
int fd = open(argv[1],O_RDONLY,0666);
-
if(-1 == fd) printf("文件打开失败:%m\n"),close(clientSocket),exit(-3);
-
printf("文件打开成功!\n");
-
//3.1 获取文件大小
-
struct stat st = {0};
-
stat(argv[1],&st);
-
printf("文件大小为: %d\n",(int)st.st_size);
-
printf("文件名为:%s\n",argv[1]);
-
sleep(2);
-
//3.2 将文件名和文件大小发送给服务器(注意先后顺序)
-
sendto(clientSocket,argv[1],strlen(argv[1]),0,
-
(struct sockaddr*)&cAddr,sizeof cAddr);
-
sleep(2);
-
sendto(clientSocket,(char*)&st.st_size,4,0,
-
(struct sockaddr*)&cAddr,sizeof cAddr);
-
//3.3 读取内容并发送
-
sleep(2);
-
char buff[1024] = {0};
-
while(1){
-
int r = read(fd,buff,1024);
-
if(r > 0)
-
sendto(clientSocket,buff,r,0,
-
(struct sockaddr*)&cAddr,sizeof cAddr);
-
else
-
break;
-
}
-
//4. 文件传输完成
-
sleep(1);
-
close(fd);
-
close(clientSocket);
-
printf("bye bye!\n");
-
return 0;
-
}
6. TCP通信与UDP通信的优缺点
6.1 TCP通信优缺点
6.1.1 优点
TCP可以建立稳定的连接,并且可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
6.1.2 缺点
数据传输速率慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
6.2 UDP通信优缺点
6.2.1 优点
数据传输速率快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。
6.2.2 缺点
不能像TCP那样建立稳定的连接并且不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。