本次實驗利用TCP/IP, 語言環境為 C/C++
利用套接字Socket編程,實現Server/CLient 之間簡單的通訊。
結果應為類似所示:

下面貼上代碼(參考參考...)
Server 部分:
1 /* TCPServer.cpp - main */ 2 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <winsock2.h> 6 #include <time.h> 7 #include "conio.h" 8 9 #define QLEN 5 10 #define WSVERS MAKEWORD(2, 0) 11 #define BUFLEN 20000 12 #pragma comment(lib,"ws2_32.lib") //使用winsock 2.2 library 13 /*------------------------------------------------------------------------ 14 * main - Iterative TCP server for TIME service 15 *------------------------------------------------------------------------ 16 */ 17 char buf[20000]; 18 char buf1[20000]; 19 char buf2[20000]; 20 void main(int argc, char *argv[]) 21 /* argc: 命令行參數個數, 例如:C:\> TCPServer 8080 22 argc=2 argv[0]="TCPServer",argv[1]="8080" */ 23 { 24 struct sockaddr_in fsin; /* the from address of a client */ 25 SOCKET msock, ssock; /* master & slave sockets */ 26 WSADATA wsadata; 27 char *service = "5050"; 28 struct sockaddr_in sin; /* an Internet endpoint address */ 29 int alen; /* from-address length */ 30 char *pts; /* pointer to time string */ 31 // char pts[2000]; 32 time_t now; /* current time */ 33 int cc; 34 35 WSAStartup(WSVERS, &wsadata); // 加載winsock library。WSVERS指明請求使用的版本。wsadata返回系統實際支持的最高版本 36 msock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // 創建套接字,參數:因特網協議簇(family),流套接字,TCP協議 37 // 返回:要監聽套接字的描述符或INVALID_SOCKET 38 39 memset(&sin, 0, sizeof(sin)); // 從&sin開始的長度為sizeof(sin)的內存清0 40 sin.sin_family = AF_INET; // 因特網地址簇(INET-Internet) 41 sin.sin_addr.s_addr = INADDR_ANY; // 監聽所有(接口的)IP地址。 42 sin.sin_port = htons((u_short)atoi(service)); // 監聽的端口號。atoi--把ascii轉化為int,htons--主機序到網絡序(16位) 43 bind(msock, (struct sockaddr *)&sin, sizeof(sin)); // 綁定監聽的IP地址和端口號 44 45 listen(msock, 5); // 等待建立連接的隊列長度為5 46 47 while(!_kbhit()){ // 檢測是否有按鍵 48 alen = sizeof(struct sockaddr); // 取到地址結構的長度 49 ssock = accept(msock, (struct sockaddr *)&fsin, &alen); // 如果有新的連接請求,返回連接套接字,否則,被阻塞。fsin包含客戶端IP地址和端口號 50 51 (void) time(&now); // 取得系統時間 52 pts = ctime(&now); // 把時間轉換為字符串 53 sprintf(buf,"IP :%s 端口號: %d\n",inet_ntoa(fsin.sin_addr),fsin.sin_port); 54 // sprintf(buf,"%d:%d Hello my friends ! %s",inet_ntoa(sin.sin_addr),fsin.sin_port,pts); 55 (void) send(ssock, buf, strlen(pts), 0); // 把緩沖區(指針,長度)的數據發送出去 56 printf(" TCP(Server) Echo增強程序 \n\n"); 57 printf(" 時間: %s\n", pts); 58 printf(" %s\n", buf); // 顯示發送字符串 59 printf("請等待接收數據 :\n"); 60 61 //flag1: 62 // printf("\n您還要傳送什么?\n"); 63 // printf(" 如果想臨時改為接收,請鍵入 * \n"); 64 // scanf("%s",pts); 65 66 // if(pts[0] == '*') 67 // { 68 // printf("\n請等待接收數據\n"); 69 // sprintf(buf1,"%s",pts); 70 // (void) send(ssock, buf1, strlen(pts), 0); 71 // goto flag2; 72 // } 73 // sprintf(buf1,"%s",pts); 74 // (void) send(ssock, buf1, strlen(pts), 0); 75 // goto flag1; 76 // ssock = accept(msock, (struct sockaddr *)&fsin, &alen); 77 78 flag2: cc = recv(ssock, buf1, BUFLEN, 0); 79 if(cc == SOCKET_ERROR || cc==0) 80 printf("Error: %d.\n",GetLastError()); //出錯。其后必須關閉套接字sock。 81 else if(cc > 0) { 82 buf1[cc] = '\0'; // ensure null-termination 83 buf2[cc] = '\0'; 84 // if(buf1[0] == '#') 85 // { 86 // printf("\n您接收到的數據為: # , 請傳輸數據 \n"); 87 // goto flag2; 88 // } 89 (void) time(&now); 90 pts = ctime(&now); 91 sprintf(buf2,"%s \n %s",pts,buf1); 92 // strcat(buf2,buf1); 93 printf("\n您接收到的數據為:"); 94 // printf(" 時間: %s\n", pts); 95 printf("%s\n", buf2); 96 printf("\n 將自動把此數據返回給客戶!\n"); 97 (void) send(ssock, buf1, strlen(pts), 0); 98 goto flag2; 99 } 100 (void) closesocket(ssock); // 關閉連接套接字 101 } 102 (void) closesocket(msock); // 關閉監聽套接字 103 WSACleanup(); // 卸載winsock library 104 105 }
Client 部分:
1 /* TCPClient.cpp */ 2 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <winsock2.h> 6 #include <string.h> 7 #include <time.h> 8 #include "conio.h" 9 #define BUFLEN 20000 // 緩沖區大小 10 #define WSVERS MAKEWORD(2, 0) // 指明版本2.0 11 #pragma comment(lib,"ws2_32.lib") // 使用winsock 2.0 Llibrary 12 13 /*------------------------------------------------------------------------ 14 * main - TCP client for TIME service 15 *------------------------------------------------------------------------ 16 */ 17 char buf1[BUFLEN+1]; 18 char buf[BUFLEN+1]; /* buffer for one line of text */ 19 void main(int argc, char *argv[]) 20 { 21 char *host = "127.0.0.1"; 22 // char *host = "10.4.4.146"; /* server IP to connect */ 23 24 char *service = "5050"; /* server port to connect */ 25 struct sockaddr_in sin,fsin; /* an Internet endpoint address */ 26 27 28 SOCKET sock,ssock; /* socket descriptor */ 29 int cc,alen; /* recv character count */ 30 char *pts ; 31 time_t now; 32 WSADATA wsadata; 33 WSAStartup(WSVERS, &wsadata); //加載winsock library。WSVERS為請求的版本,wsadata返回系統實際支持的最高版本 34 35 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //創建套接字,參數:因特網協議簇(family),流套接字,TCP協議 36 37 //返回:要監聽套接字的描述符或INVALID_SOCKET 38 39 memset(&sin, 0, sizeof(sin)); // 從&sin開始的長度為sizeof(sin)的內存清0 40 sin.sin_family = AF_INET; // 因特網地址簇 41 sin.sin_addr.s_addr = inet_addr(host); // 服務器IP地址(32位) 42 sin.sin_port = htons((u_short)atoi(service)); // 服務器端口號 43 connect(sock, (struct sockaddr *)&sin, sizeof(sin)); // 連接到服務器 44 // alen = sizeof(struct sockaddr); 45 // ssock = accept(sock, (struct sockaddr *)&fsin, &alen); 46 printf(" TCP(Client) Echo增強程序 \n\n"); 47 flag1: cc = recv(sock, buf1, BUFLEN+1, 0); // cc為接收到的字符的個數(>0)或對方已關閉(=0)或連接出錯(<0) 48 if(cc == SOCKET_ERROR || cc==0) 49 printf("Error: %d.\n",GetLastError()); //出錯。其后必須關閉套接字sock。 50 else if(cc > 0) { 51 buf1[cc] = '\0'; // ensure null-termination 52 // if(buf[0] == '*') 53 // { 54 // printf("\n您接收到的數據為: * , 請傳輸數據 \n"); 55 // goto flag2; 56 // } 57 (void) time(&now); // 取得系統時間 58 pts = ctime(&now); 59 printf("您接收到的數據為:\n"); 60 printf(" 時間: %s\n",pts); 61 printf(" %s\n",buf1); // 顯示所接收的字符串 62 } 63 goto flag2; 64 65 flag2: 66 67 68 69 printf("\n您想傳送什么?\n"); 70 printf(" 如果想關閉連接,請輸入 @ \n"); 71 // printf("\n 如果想臨時改為接收,請鍵入 # \n"); 72 scanf("%s",pts); 73 if(pts[0] == '@') 74 goto end; 75 // if(pts[0] == '#') 76 // { 77 // printf("\n請等待接收數據\n"); 78 // sprintf(buf1,"%s",pts); 79 // (void) send(sock, buf1, strlen(pts), 0); 80 // goto flag1; 81 // } 82 sprintf(buf1,"%s",pts); 83 (void) send(sock, buf1, strlen(pts), 0); 84 goto flag1; 85 end: closesocket(sock); // 關閉監聽套接字 86 87 WSACleanup(); // 卸載winsock library 88 89 printf("\n按回車鍵繼續..."); 90 getchar(); // 等待任意按鍵 91 }
