• 【Echo】实验 -- 实现 C/C++下UDP, 服务器/客户端 通讯


    本次实验利用UDP协议, 语言环境为 C/C++

    利用套接字Socket编程,实现Server/CLient 之间简单的通讯。

    结果应为类似所示:

    下面贴上代码(参考参考...)

    Server 部分:

     1 /* UDPServer.cpp */
     2 
     3 #include <stdlib.h>
     4 #include <stdio.h>
     5 #include <winsock2.h>
     6 #include <string.h>
     7 #include "conio.h"
     8 #include <time.h>
     9 
    10 #define    BUFLEN        2000                  // 缓冲区大小
    11 #define WSVERS        MAKEWORD(2, 2)        // 指明版本2.2 
    12 #pragma comment(lib,"ws2_32.lib")         // 加载winsock 2.2 Llibrary
    13 
    14 /*------------------------------------------------------------------------
    15  * main - TCP client for DAYTIME service
    16  *------------------------------------------------------------------------
    17  */
    18 void
    19 main(int argc, char *argv[])
    20 {
    21     char   *host = "127.0.0.1";        /* server IP Address to connect */
    22 
    23     char   *service = "5050";          /* server port to connect       */
    24     struct sockaddr_in sin;            /* an Internet endpoint address    */
    25     struct sockaddr_in from;        /* sender address               */
    26     int    fromsize = sizeof(from);
    27     char   buf[BUFLEN+1];           /* buffer for one line of text    */
    28     char   buf1[BUFLEN+1];  
    29     SOCKET    sock;                      /* socket descriptor            */
    30     int    cc;                            /* recv character count            */
    31 
    32     char    *pts;    
    33     time_t    now;
    34 
    35     WSADATA wsadata;
    36     WSAStartup(WSVERS, &wsadata);   /* 加载winsock library,WSVERS为请求版本,wsadata返回系统实际支持的最高版本。    */        
    37     sock = socket(PF_INET, SOCK_DGRAM,IPPROTO_UDP); // 创建UDP套接字, 参数:因特网协议簇(family),数据报套接字,UDP协议号, 返回:要监听套接字的描述符或INVALID_SOCKET
    38     memset(&sin, 0, sizeof(sin));
    39     sin.sin_family = AF_INET;
    40     sin.sin_addr.s_addr = INADDR_ANY;                     // 绑定(监听)所有的接口。
    41     sin.sin_port = htons((u_short)atoi(service));         // 绑定指定接口。atoi--把ascii转化为int,htons -- 主机序(host)转化为网络序(network), 为short类型。 
    42     bind(sock, (struct sockaddr *)&sin, sizeof(sin));     // 绑定本地端口号(和本地IP地址)
    43 
    44     (void) time(&now);                                      // 取得系统时间
    45        pts = ctime(&now);                                      // 把时间转换为字符串
    46        printf("           	     UDP(Server) Echo增强程序
    
    "); 
    47      while(!_kbhit()){                                    //检测是否有按键
    48 flag1:        cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&from, &fromsize);  //接收客户数据。返回结果:cc为接收的字符数,from中将包含客户IP地址和端口号。
    49         sprintf(buf1," 		 时间:  %s 		 Client【IP: %s  端口号: %d  】
      		  数据:   %s",pts,inet_ntoa(from.sin_addr),from.sin_port,buf);
    50         if (cc == SOCKET_ERROR){
    51             printf("recvfrom() failed; %d
    ", WSAGetLastError());
    52             break;
    53         }
    54         else if (cc == 0)
    55             break;
    56         else{
    57             buf[cc] = '';
    58             printf("您收到的数据为:
       %s
    ", buf1);
    59             printf("将自动把此数据返回给 Client  
    ");
    60             goto flag2;
    61         }
    62 
    63     }
    64 
    65 flag2:    cc = sendto(sock, buf1, 1000, 0,(SOCKADDR *)&from, sizeof(from));
    66    if (cc == SOCKET_ERROR){
    67         printf("发送失败,错误号:%d
    ", WSAGetLastError());
    68           }
    69     else{
    70         printf("发送成功
    ");
    71         goto flag1;
    72          }
    73 
    74 //    cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&from, &fromsize);
    75 
    76     closesocket(sock);
    77     GlobalFree(buf);
    78     WSACleanup();                     /* 卸载某版本的DLL */
    79 }
    View Code

    Client 部分:

     1 /* UDPClient.cpp */
     2 
     3 #include <stdlib.h>
     4 #include <stdio.h>
     5 #include <winsock2.h>
     6 #include <string.h>
     7 #include <time.h>
     8 
     9 #define    BUFLEN        2000                  // 缓冲区大小
    10 #define WSVERS        MAKEWORD(2, 2)        // 指明版本2.2 
    11 #pragma comment(lib,"ws2_32.lib")         // 加载winsock 2.2 Llibrary
    12 
    13 void
    14 main(int argc, char *argv[])
    15 {
    16     char    *host = "127.0.0.1";        /* server IP to connect         */
    17 
    18     char    *service = "5050";          /* server port to connect       */
    19     struct sockaddr_in toAddr;            /* an Internet endpoint address    */
    20     char    buf[BUFLEN+1];                   /* buffer for one line of text    */
    21     SOCKET    sock;                          /* socket descriptor            */
    22     int    cc;                                /* recv character count            */
    23     char    *pts;                    /* pointer to time string            */
    24     time_t    now;                    /* current time                        */
    25 
    26     int    toAddrsize = sizeof(toAddr);
    27 
    28     WSADATA wsadata;
    29     WSAStartup(WSVERS, &wsadata);       /* 启动某版本Socket的DLL        */    
    30 
    31     sock = socket(PF_INET, SOCK_DGRAM,IPPROTO_UDP);
    32 
    33     memset(&toAddr, 0, sizeof(toAddr));
    34     toAddr.sin_family = AF_INET;
    35     toAddr.sin_port = htons((u_short)atoi(service));    //atoi:把ascii转化为int. htons:主机序(host)转化为网络序(network), s--short
    36     toAddr.sin_addr.s_addr = inet_addr(host);           //如果host为域名,需要先用函数gethostbyname把域名转化为IP地址
    37 
    38 
    39 //    memset(buf,' ',1000);  //fill 1000 bytes with 'e'
    40     buf[1000] = '';
    41     (void) time(&now);                                      // 取得系统时间
    42     pts = ctime(&now);                                      // 把时间转换为字符串
    43 //    memcpy(buf,pts,strlen(pts));
    44     sprintf(buf,"%s ",pts);
    45     printf("                        UDP(Client) Echo增强程序
    
    "); 
    46      printf("  时间 :%s",buf);
    47 
    48 
    49 
    50     cc = sendto(sock, buf, 1000, 0,(SOCKADDR *)&toAddr, sizeof(toAddr));
    51  flag2:   if (cc == SOCKET_ERROR){
    52         printf("发送失败,错误号:%d
    ", WSAGetLastError());
    53      }
    54     else{
    55         printf("       发送成功 
    ");
    56          cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&toAddr, & toAddrsize);
    57          printf(" 您接收到的数据为:
     %s 
    ",buf);
    58         printf("键入 # 继续发送,键入 @ 停止发送
    ");
    59         scanf("%s",pts);
    60         if(pts[0]=='#')
    61         {
    62             printf("    请输入要发送的数据 :
    ");
    63             goto flag1;
    64         }
    65         if(pts[0]=='@')
    66             goto end;
    67 
    68 
    69     }
    70 
    71 flag1:
    72     scanf("%s",pts);
    73     sprintf(buf,"%s ",pts);
    74     cc = sendto(sock, buf, 1000, 0,(SOCKADDR *)&toAddr, sizeof(toAddr));
    75 
    76     goto flag2;
    77 
    78 
    79 
    80     getchar();
    81 
    82     closesocket(sock);
    83 
    84 end:    GlobalFree(buf);
    85     WSACleanup();                     /* 卸载某版本的DLL */  
    86 
    87     getchar();
    88 
    89 }
    View Code
  • 相关阅读:
    有赞个性化推荐能力的演进与实践
    Doge.jpg 的背后是什么,你知道么?
    实操|如何将 Containerd 用作 Kubernetes runtime
    Linux 用键盘操作窗口
    Oracle中join left,join right,inner join,(+) 等
    sql之left join、right join、inner join的区别
    SQL中GROUP BY的用法
    Oracle CASE WHEN 用法介绍
    Oracle数据库面试题
    Oracle笔试题库之问答题篇-总共60道
  • 原文地址:https://www.cnblogs.com/imwtr/p/4072422.html
Copyright © 2020-2023  润新知