Linux C/C++之TCP / UDP通信
目錄
1. 什么是網絡
1.1 網絡的定義
1.2 網絡的實質
1.3 主機的類型
1.4 信息的傳遞
2. 網絡分層
2.1 五層模型
2.2 七層模型(OSI Open System Interconnection)
?2.3 每層作用以及相關協議
3. ip, 網關,子網掩碼,端口
3.1 ip(Internet Protocol)
3.2 網關
3.3 子網掩碼
3.4 端口
4. 大小端系統
4.1 大端系統
4.2 小端系統
4.3 注意事項
5. 什么是協議
5.1 協議的實質
5.2 協議的分類
6. 傳輸層協議之TCP通信
6.1 TCP通信編程模型
6.2 TCP實現簡單通信
6.2.1 Server端
6.2.2 Client端
6.3 TCP實現文件傳輸
6.3.1?實現連接后,文件傳輸步驟
6.3.2?server(接收文件)端
6.3.3?client(發送文件)端
7. 傳輸層協議之UDP通信
7.1 UDP通信編程模型
7.2 UDP實現簡單通信
7.2.1 Server端
7.2.2 Client端
7.3 UDP實現文件傳輸
7.3.1 Server(文件接收)端
7.3.2 Client(文件發送)端
8. TCP通信與UDP通信的優缺點
8.1 TCP通信優缺點
8.1.1?優點
8.1.2?缺點
8.2 UDP通信優缺點
8.2.1?優點
8.2.2?缺點
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. 大小端系統
4.1 大端系統
低位數據存放在高地址,高位數據存放在低地址。
4.2 小端系統
低位數據存放在低地址,高位數據存放在高地址。
4.3 注意事項
????????網絡服務器均為大端系統(因為網絡服務器一般是UNIX系統),因此在編寫網絡通信的代碼時需要將小端轉換為大端
大小端存儲模型
?小端系統的存儲
#include <stdio.h>union uu{char c[4];int n; }; int main(){//類型 決定 存儲方式 和 占用空間大小//int 4字節 x86架構 arm架構 ......//0x11223344 小端系統 大端系統union uu u;u.n = 0x11223344;printf("%x %x %x %x\n",u.c[0],u.c[1],u.c[2],u.c[3]);return 0; }5. 什么是協議
5.1 協議的實質
????????協議就像我們在學校需要遵守的規矩一樣,網絡通信也是如此,只有當服務器與客戶端均遵守相同的規矩(協議)它們之間才能完成通信。
5.2 協議的分類
????????公有協議:大部分人都遵守的規矩。
????????私有協議:部分人遵守的協議。例如對講機,遠程監控使用公有協議就會存在安全問題,一般數據鏈路層和物理層均使用私有協議。
6. 傳輸層協議之TCP通信
6.1 TCP通信編程模型
| 服務器(server) | 客戶端(client) |
| ? ? ? ? 1. 創建socket? ? | ????????1. 創建socket |
| ????????2. 確定服務器協議地址簇?? | ????????2. 獲取服務器協議地址簇 |
| ????????3. 綁定 | |
| ? ? ? ? 4. 監聽 | |
| ? ? ? ? 5. 接受連接? ? | ? ? ? ? 3.? 連接服務器 |
| ? ? ? ? 6. 通信? ? | ? ? ? ? 4. 通信 |
| ????????7. 斷開連接? ? ? | ? ? ? ??5. 斷開連接 |
6.2 TCP實現簡單通信
6.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; }6.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; }6.3 TCP實現文件傳輸
6.3.1?實現連接后,文件傳輸步驟
| 接收端(Server) | 發送端(Client) |
| 1.?等待客戶端發送 | 1. 發送文件名 |
| 2.?接收文件名并創建文件 | 2.?獲取文件大小并發送 |
| 3.?接收文件大小并打開文件 | 3.?打開文件準備讀取發送 |
| 4.?循環接收并寫入文件 | 4.?循環讀取文件并發送文件內容 |
| 5.?寫入數據完畢,關閉文件和連接 | 5.? 發送數據完畢,關閉文件和連接 |
6.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函數為阻塞函數
6.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);elsebreak;}//5. 關閉文件sleep(1);close(fd);close(clientSocket);printf("文件發送完畢!\n");return 0; }7. 傳輸層協議之UDP通信
7.1 UDP通信編程模型
| 服務器(Server) | 客戶端(Client) |
| 1.?創建Socket | 1.?創建Socket |
| 2.?確定服務器協議地址簇 | 2.?獲取服務器協議地址簇 |
| 3.?綁定 | |
| 4.?通信 | 3.?通信 |
7.2 UDP實現簡單通信
7.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. 關閉serverSocketclose(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; }7.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; }?這樣就實現了傻瓜式的一應一答的雙向通信
?
7.3 UDP實現文件傳輸
7.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. 關閉serverSocketsleep(1);close(fd);close(serverSocket);printf("bye bye!\n");return 0; }7.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);elsebreak;}//4. 文件傳輸完成sleep(1);close(fd);close(clientSocket);printf("bye bye!\n");return 0; }8. TCP通信與UDP通信的優缺點
8.1 TCP通信優缺點
8.1.1?優點
????????TCP可以建立穩定的連接,并且可靠,穩定 TCP的可靠體現在TCP在傳遞數據之前,會有三次握手來建立連接,而且在數據傳遞時,有確認、窗口、重傳、擁塞控制機制,在數據傳完后,還會斷開連接用來節約系統資源。
8.1.2?缺點
? ? ? ? 數據傳輸速率慢,效率低,占用系統資源高,易被攻擊 TCP在傳遞數據之前,要先建連接,這會消耗時間,而且在數據傳遞時,確認機制、重傳機制、擁塞控制機制等都會消耗大量的時間,而且要在每臺設備上維護所有的傳輸連接,事實上,每個連接都會占用系統的CPU、內存等硬件資源。 而且,因為TCP有確認機制、三次握手機制,這些也導致TCP容易被人利用,實現DOS、DDOS、CC等攻擊。
8.2 UDP通信優缺點
8.2.1?優點
????????數據傳輸速率快,比TCP稍安全 UDP沒有TCP的握手、確認、窗口、重傳、擁塞控制等機制,UDP是一個無狀態的傳輸協議,所以它在傳遞數據時非常快。沒有TCP的這些機制,UDP較TCP被攻擊者利用的漏洞就要少一些。
8.2.2?缺點
????????不能像TCP那樣建立穩定的連接并且不可靠,不穩定 因為UDP沒有TCP那些可靠的機制,在數據傳遞時,如果網絡質量不好,就會很容易丟包。
總結
以上是生活随笔為你收集整理的Linux C/C++之TCP / UDP通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: icem网格划分如何给内部面网格,ICE
- 下一篇: Ubuntu20.04 安装向日葵Sun