計算機網路_驗證UDP特性(一次未將報文資料讀完,剩餘部分將被丟棄)
阿新 • • 發佈:2018-12-01
一、 思路
伺服器端和客戶端進行報文互動,客戶端每次向伺服器端傳送訊息,伺服器端只讀取5個有效字元,觀察情況:
二、 程式碼實現
#include<netinet/in.h> //struct sockaddr; struct sockaddr_in;
#include<sys/socket.h> //socket() bind() recvfrom() sendto()
#include<arpa/inet.h> //位元組序 htons() 返回以網路位元組序表示的16位無符號
#include<string.h> //memset()
#include<assert.h> //assert()
#include<stdio.h> //printf()
2.1 伺服器端
#include<netinet/in.h> //struct sockaddr; struct sockaddr_in; #include<sys/socket.h> //socket() bind() recvfrom() sendto() #include<arpa/inet.h> //位元組序 htons() 返回以網路位元組序表示的16位無符號 #include<string.h> //memset() #include<assert.h> //assert() #include<stdio.h> //printf() int main() { int sockfd = socket(AF_INET, SOCK_DGRAM, 0);//地址族 套接字型別 協議 assert(-1 != sockfd); struct sockaddr_in ser, cli; memset(&ser, 0, sizeof(ser)); //格式化伺服器端 //設定伺服器端套接字 ser.sin_family = AF_INET; //ipV4 ser.sin_port = htons(6500); //埠號為6000 主機序-> 網路序 ser.sin_addr.s_addr = inet_addr("127.0.0.1");//ip地址 //將套接字和地址結構進行繫結 int res = bind(sockfd, (struct sockaddr*)&ser, sizeof(ser)); assert(-1 != res); while(1) { char recvbuf[6] = {'\0'}; //接受5個有效字元 保留一個結束符 int len = sizeof(cli); //套接字緩衝區的大小可能會改變 int n = recvfrom(sockfd, recvbuf, 5, 0, (struct sockaddr*)&cli, &len); if(n <= 0) //本次失敗繼續進行下一次客戶機和伺服器端通訊 { printf("recvfrom error!\n"); continue; } printf("%s\n", recvbuf); //列印輸出從客戶端接收的資料 } close(sockfd); //關閉伺服器端套接字 }
2.2 客戶端
#include<string.h> //memset() #include<arpa/inet.h> //位元組序處理 htons() #include<sys/socket.h> //sendto() recvfrom() socket() #include<netinet/in.h> //struct sockaddr; struct sockaddr_in; #include<assert.h> //assert() #include<stdio.h> //printf() #include<stdlib.h> //exit() //main主函式傳參 argc反映陣列argv元素的個數 int main(int argc, char* argv[]) { if(argc < 3) { printf("please choose server's IP && port\n"); exit(0); } //從命令列讀入埠號 int port; sscanf(argv[2], "%d", &port); //地址族 套機字型別 所使用的協議 值位0表明和套接字型別自動匹配的協議 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); assert(-1 != sockfd); struct sockaddr_in ser, cli; memset(&ser, 0, sizeof(ser)); //配置伺服器端地址 ser.sin_family = AF_INET; ser.sin_addr.s_addr = inet_addr(argv[1]); ser.sin_port = htons(port); while(1) { //列印輸出提示語句 printf("please input:"); fflush(stdout); char buf[128] = {'\0'}; fgets(buf, 127, stdin); //留下1位用作結束符 buf[strlen(buf) - 1] = '\0'; if(0 == strncmp(buf, "end", 3)) //客戶端命令列輸入end { close(sockfd); break; } sendto(sockfd, buf, strlen(buf), 0,(struct sockaddr*)&ser, sizeof(ser)); } close(sockfd); //關閉檔案描述符 }
2.3 執行結果
如圖 1所示,不管客戶機輸入的報文是長或段,因為在伺服器端的程式碼實現中,一次只會讀取5個有效字元。那如果伺服器端收到的字元多於5個怎麼辦?UDP是這樣處理的:你可以沒有時間處理,核心會為你保留;但是一旦進行讀取,必須一次性將報文全部讀取完,剩下的直接丟棄。