UDP協議----簡單的CS模型實現


UDP簡單介紹

  傳輸層主要應用的協議模型有兩種,一種是TCP協議,另外一種則是UDP協議。TCP協議在網絡通信中占主導地位,絕大多數的網絡通信借助TCP協議完成數據傳輸。但UDP也是網絡通信中不可或缺的重要通信手段。

  相較於TCP而言,UDP通信的形式更像是發短信。不需要在數據傳輸之前建立、維護連接。只專心獲取數據就好。省去了三次握手的過程,通信速度可以大大提高,但與之伴隨的通信的穩定性和正確率便得不到保證。因此,我們稱UDP為“無連接的不可靠報文傳遞”。

  那么與我們熟知的TCP相比,UDP有哪些優點和不足呢?由於無需創建連接,所以UDP開銷較小,數據傳輸速度快,實時性較強。多用於對實時性要求較高的通信場合,如視頻會議、電話會議等。但隨之也伴隨着數據傳輸不可靠,傳輸數據的正確率、傳輸順序和流量都得不到控制和保證。所以,通常情況下,使用UDP協議進行數據傳輸,為保證數據的正確性,我們需要在應用層添加輔助校驗協議來彌補UDP的不足,以達到數據可靠傳輸的目的。

  如下圖所示,簡單的UDP的CS模型通信過程,由於UDP不需要維護連接,程序邏輯簡單了很多,但是UDP協議是不可靠的,保證通訊可靠性的機制需要在應用層實現。

  

代碼實現:

server.c

 1 #include<stdio.h>
 2 #include<unistd.h>
 3 #include<stdlib.h>
 4 #include<sys/socket.h>
 5 #include<string.h>
 6 #include<arpa/inet.h>
 7 #include<ctype.h>
 8 
 9 #define SERVER_PORT 8000
10 
11 int main(int agrc,char* argv[])
12 {
13     int sockfd;
14     struct sockaddr_in servaddr,clieaddr;
15     socklen_t clieaddr_len;
16     char buf[BUFSIZ];
17     char str[INET_ADDRSTRLEN];
18     int i,n;
19 
20     sockfd=socket(AF_INET,SOCK_DGRAM,0);
21     bzero(&servaddr,sizeof(servaddr));
22     servaddr.sin_family=AF_INET;
23     servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
24     servaddr.sin_port=htons(SERVER_PORT);
25 
26     bind(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
27 
28     printf("Acceptint Connections ...\n");
29     while(1)
30     {
31         clieaddr_len=sizeof(clieaddr);
32         n=recvfrom(sockfd,buf,BUFSIZ,0,(struct sockaddr*)&clieaddr,&clieaddr_len);
33         if(n==-1)
34         {
35             perror("recvfrom error");
36         }
37         printf("received from %s at PORT %d\n",inet_ntop(AF_INET,&clieaddr.sin_addr,str,sizeof(str)),ntohs(clieaddr.sin_port));
38         for(i=0;i<n;i++)
39         {
40             buf[i]=toupper(buf[i]);
41         }
42         n=sendto(sockfd,buf,n,0,(struct sockaddr*)&clieaddr,sizeof(clieaddr));
43         if(n==-1)
44         {
45             perror("sendto error");
46         }
47     }
48     close(sockfd);
49 
50     return 0;
51 }

client.c

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<unistd.h>
 4 #include<arpa/inet.h>
 5 #include<ctype.h>
 6 
 7 #define SERVER_PORT 8000
 8 
 9 int main(int argc,char* argv[])
10 {
11     struct sockaddr_in servaddr;
12     int sockfd,n;
13     char buf[BUFSIZ];
14 
15     sockfd = socket(AF_INET,SOCK_DGRAM,0);
16 
17     bzero(&servaddr,sizeof(servaddr));
18     servaddr.sin_family = AF_INET;
19     inet_pton(AF_INET,"0.0.0.0",&servaddr.sin_addr);
20     servaddr.sin_port = htons(SERVER_PORT);
21 
22     bind(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
23 
24     while(fgets(buf,BUFSIZ,stdin)!= NULL)
25     {
26         n = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&servaddr,sizeof(servaddr));
27         if(n == -1)
28         {
29             perror("sendto error");
30             //printf("*********************\n");
31         }
32         n = recvfrom(sockfd,buf,BUFSIZ,0,NULL,0);//NULL:不關心對端信息
33         if(n == -1)
34         {
35             perror("recvfrom error");
36         }
37         write(STDOUT_FILENO,buf,n);
38     }
39     close(sockfd);
40     return 0;
41 }

測試結果:

 

1.首先啟動服務端程序

2.再啟動客戶端程序

3.在客戶端輸入一個字符串回車

4.在客戶端可以看到服務端轉換的大寫字符串回寫到客戶端屏幕

5.服務端可以看到客戶端連接的信息(IP和端口號)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM