zoukankan      html  css  js  c++  java
  • 基于UDP的一对回射客户/服务器程序

    前言

      之前曾经学习过一对回射客户/服务器程序的例子,不过那个是基于TCP协议的。本文将讲解另一对回射客户/服务器程序,该程序基于UDP协议。由于使用的协议不同,因此编写出的程序也有本质上的区别,应将它们对比来进行理解。

    通信框架

      

    服务器端

     1 #include    "unp.h"
     2 
     3 int
     4 main(int argc, char **argv)
     5 {
     6     int                    sockfd;
     7     struct sockaddr_in    servaddr, cliaddr;
     8 
     9     // 创建UDP套接字
    10     sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
    11 
    12     bzero(&servaddr, sizeof(servaddr));
    13     servaddr.sin_family      = AF_INET;
    14     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    15     servaddr.sin_port        = htons(SERV_PORT);
    16 
    17     Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
    18 
    19     dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
    20 }
     1 #include    "unp.h"
     2 
     3 void
     4 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
     5 {
     6     int            n;
     7     socklen_t    len;
     8     char        mesg[MAXLINE];
     9 
    10     for ( ; ; ) {
    11         len = clilen;
    12         // 接收数据
    13         n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
    14 
    15         // 回射数据
    16         Sendto(sockfd, mesg, n, 0, pcliaddr, len);
    17     }
    18 }

    客户端

     1 #include    "unp.h"
     2 
     3 int
     4 main(int argc, char **argv)
     5 {
     6     int                    sockfd;
     7     struct sockaddr_in    servaddr;
     8 
     9     if (argc != 2)
    10         err_quit("usage: udpcli <IPaddress>");
    11 
    12     bzero(&servaddr, sizeof(servaddr));
    13     servaddr.sin_family = AF_INET;
    14     servaddr.sin_port = htons(SERV_PORT);
    15     Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    16 
    17     // 创建UDP套接字
    18     sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
    19 
    20     dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
    21 
    22     exit(0);
    23 }
     1 #include    "unp.h"
     2 
     3 void
     4 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
     5 {
     6     int                n;
     7     char            sendline[MAXLINE], recvline[MAXLINE + 1];
     8     socklen_t        len;
     9     struct sockaddr    *preply_addr;
    10 
    11     preply_addr = Malloc(servlen);
    12 
    13     while (Fgets(sendline, MAXLINE, fp) != NULL) {
    14 
    15         // 往服务器发送数据
    16         Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
    17 
    18         len = servlen;
    19         n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
    20         // 不接收非指定服务器的数据
    21         if (len != servlen || memcmp(pservaddr, preply_addr, len) != 0) {
    22             printf("reply from %s (ignored)
    ",
    23                     Sock_ntop(preply_addr, len));
    24             continue;
    25         }
    26 
    27         // 将回射结果打印给用户
    28         recvline[n] = 0;    /* null terminate */
    29         Fputs(recvline, stdout);
    30     }
    31 }

    小结

      1. UDP的机制比起TCP来说,简单多了。但也因此缺少了重传机制,验证相应是否来自对端等等可靠性相关的性质

      2. 只有被 connect 后的UDP套接字才能收到异常信息。

  • 相关阅读:
    博客园的使用和设置
    关于递推算法求解约瑟夫环问题P(n,m,k,s)
    HTML超链接和路径
    HTML文本元素标签
    HTML前序
    Java正则表达式验证至少6位表达式中至少包含数字大小写字母中的一种
    创建自己的第一个Vue项目
    查看端口及进程
    Java读取数据库(Oracle,MySQL,PostgresSQL)表信息以及字段信息生成Word文档
    启动项目报错ORA-12505, TNS:listener does not currently know of SID given in
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3641733.html
Copyright © 2011-2022 走看看