本次實驗利用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 }
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 }