zoukankan      html  css  js  c++  java
  • 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和端口号)

    努力不一定有结果,有结果不一定是努力
  • 相关阅读:
    暑假第二十七测
    暑假第二十七测
    【真题解】牛宫
    【伪题解】牛宫
    最优贸易
    跳马问题
    求和问题
    【题解】山区建小学
    OpenStack之虚机冷迁移代码简析
    OpenStack之虚机热迁移代码解析
  • 原文地址:https://www.cnblogs.com/liunianshiwei/p/6050396.html
Copyright © 2011-2022 走看看