【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("           \t     UDP(Server) Echo增強程序\n\n"); 
47      while(!_kbhit()){                                    //檢測是否有按鍵
48 flag1:        cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&from, &fromsize);  //接收客戶數據。返回結果:cc為接收的字符數,from中將包含客戶IP地址和端口號。
49         sprintf(buf1," \t\t 時間:  %s \t\t Client【IP: %s  端口號: %d  】\n  \t\t  數據:   %s",pts,inet_ntoa(from.sin_addr),from.sin_port,buf);
50         if (cc == SOCKET_ERROR){
51             printf("recvfrom() failed; %d\n", WSAGetLastError());
52             break;
53         }
54         else if (cc == 0)
55             break;
56         else{
57             buf[cc] = '\0';
58             printf("您收到的數據為:\n   %s\n", buf1);
59             printf("將自動把此數據返回給 Client  \n");
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\n", WSAGetLastError());
68           }
69     else{
70         printf("發送成功\n");
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] = '\0';
41     (void) time(&now);                                      // 取得系統時間
42     pts = ctime(&now);                                      // 把時間轉換為字符串
43 //    memcpy(buf,pts,strlen(pts));
44     sprintf(buf,"%s ",pts);
45     printf("                        UDP(Client) Echo增強程序\n\n"); 
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\n", WSAGetLastError());
53      }
54     else{
55         printf("       發送成功 \n");
56          cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&toAddr, & toAddrsize);
57          printf(" 您接收到的數據為:\n %s \n",buf);
58         printf("鍵入 # 繼續發送,鍵入 @ 停止發送\n");
59         scanf("%s",pts);
60         if(pts[0]=='#')
61         {
62             printf("    請輸入要發送的數據 :\n");
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

 


免責聲明!

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



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