進擊的小白Day011——基於TCP的Socket程式設計(六)
阿新 • • 發佈:2019-02-16
把Socket程式中一些複雜的部分整合成函式,雖然有些程式碼量比較短沒必要整合,但還是鍛鍊一下這個方法吧。
#define _CRT_SECURE_NO_WARNINGS #pragma comment(lib,"ws2_32.lib") #define PORT 8888 /*定義埠*/ #define MODE 1 /*定義服務端*/ #define MAXDATA 100 /*定義最大傳輸數量*/ #define T 100 #define MAX_MAIN 10 #define MAX_RUN 10 #define MAX_MESSAGE 100 #include <windows.h> #include <time.h> #include <stdlib.h> #include <stdio.h> /*定義時間結構體*/ struct Time { long int modeTime; long int connectTime; long int messageTime; long int allowTime[MAX_RUN]; long int exeTime[MAX_RUN]; long int calTime[MAX_RUN]; long int waitTime[MAX_RUN]; long int runTime[MAX_RUN]; }; /*微秒計時函式*/ int gettimeofday(struct timeval *tp, void *tzp) { time_t clock; struct tm tm; SYSTEMTIME wtm; GetLocalTime(&wtm); tm.tm_year = wtm.wYear - 1900; tm.tm_mon = wtm.wMonth - 1; tm.tm_mday = wtm.wDay; tm.tm_hour = wtm.wHour; tm.tm_min = wtm.wMinute; tm.tm_sec = wtm.wSecond; tm.tm_isdst = -1; clock = mktime(&tm); tp->tv_sec = clock; tp->tv_usec = wtm.wMilliseconds * 1000; return 0; } /*執行演算法*/ int exe(void) { long i = 10000000L; while (i--); //printf(" This is a program that needs to be executed !\n"); return 0; } /*模式選擇函式*/ int modeChoose(void) { int mode; /*選擇服務端或客戶端*/ printf("Please choose server of client. 1.Server 2.Client\n"); scanf_s("%d", &mode); getchar(); /*mode = MODE;*/ return mode; } /*建立套接字*/ SOCKET creatSocket(void) { SOCKET Socket = socket(AF_INET, SOCK_STREAM, 0); if (Socket == -1) { printf("Socket error !"); getchar(); exit(1); } return Socket; } /*繫結IP埠*/ void bindIP(SOCKET Socket, struct sockaddr_in Socketaddr) { /*繫結IP和埠*/ Socketaddr.sin_family = AF_INET; /*定義家族協議*/ Socketaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); /*定義主機地址*/ Socketaddr.sin_port = htons(PORT); /*定義主機埠*/ if (bind(Socket, (struct sockaddr *)&Socketaddr, sizeof(Socketaddr)) == -1) /*繫結成功返回0*/ { printf("Bind error !"); getchar(); exit(1); } } /*監聽*/ void listenSocket(SOCKET Socket) { /*開始監聽*/ if (listen(Socket, 20) == -1) { printf("Listen error !"); getchar(); exit(1); } } SOCKET acceptSocket(SOCKET Socket_1, struct sockaddr_in Socketaddr_2) { int len = sizeof(struct sockaddr_in); SOCKET Socket_2 = accept(Socket_1, (SOCKADDR *)&Socketaddr_2, &len); if (Socket_2 == -1) { printf("Accept error !"); getchar(); exit(1); } return Socket_2; } void connentSocket( SOCKET Socket, struct sockaddr_in Socketaddr) { int con; /*連線服務端*/ con = -1; while (con == -1) { con = connect(Socket, (struct sockaddr*)&Socketaddr, sizeof(Socketaddr)); if (con == -1) { printf("Connect error!\n"); } } } void sendMessage(SOCKET Socket, char *Msg, int len) { /*傳送準備資訊*/ if (send(Socket, Msg, len, 0) < 0) { printf("\n\nSend error or connection interruption !\n"); getchar(); exit(1); } } char receiveMessage(SOCKET Socket) { int ret; char receiveData[MAXDATA]; /*接收準備資訊*/ ret = recv(Socket, receiveData, MAXDATA, 0); if (ret > 0) { receiveData[ret] = 0x00; printf("From client: %s\n", receiveData); } /*接收不到客戶端資料時中斷迴圈*/ else { printf("\n\nReceive error or connection interruption !\n"); getchar(); exit(1); } return receiveData; } /*字串轉換*/ char charChange(double d) { int dec_1, sign_1, dec_2, sign_2; char c; _ecvt(d, 10, &dec_1, &sign_1); c = _ecvt(d, dec_1, &dec_2, &sign_2); return c; } int compareTime(int a, int b) { int t; if (a >= b) { t = a; } else { t = b; } return t; } struct Time run(void) { /*各種定義宣告*/ SOCKET server; SOCKET client; struct sockaddr_in serveraddr; struct sockaddr_in clientaddr; WSADATA wsaData; struct Time allTime; int len = sizeof(struct sockaddr_in); int exeTime, serverTime_i, clientTime_i, ret, ret_time_server, ret_time_client; int t = T, waitTime; int mode, i; char receiveData[MAXDATA]; char runData[MAXDATA]; char byeData[MAXDATA]; char serverTime_c[MAXDATA], *serverTime_c_server, clientTime_c[MAXDATA], *clientTime_c_client; double serverTime_d, clientTime_d; clock_t startTime, endTime; /*定義計時變數*/ struct timeval start, end, allowstart, allowend, waitstart, waitend, exestart, exeend, calstart, calend; long int allowSum = 0, exeSum = 0, calSum = 0, waitSum = 0, runSum = 0; int waitTime_0[MAX_RUN]; /*微妙計時開始*/ gettimeofday(&start, NULL); mode = modeChoose(); /*服務端*/ if (mode == 1) { /*微妙計時結束,計算連線時間*/ gettimeofday(&end, NULL); allTime.modeTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; /*微妙計時開始*/ gettimeofday(&start, NULL); /*啟動windows的socket服務,初始化WSA*/ WSAStartup(0x101, &wsaData); /*建立服務端,初始化服務端地址*/ memset((void*)&serveraddr, 0, sizeof(serveraddr)); server = creatSocket(); bindIP(server, serveraddr); listenSocket(server); //printf("Waiting for connection...\n\n"); client = acceptSocket(server, serveraddr); //printf("Receive a connection: %s \r\n\n", inet_ntoa(clientaddr.sin_addr)); /*微妙計時結束,計算連線時間*/ gettimeofday(&end, NULL); allTime.connectTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; /*微妙計時開始*/ gettimeofday(&start, NULL); for (i = 0; i < MAX_MESSAGE; i++) { sendMessage(client, "I'm ready !", 11); receiveMessage(client); } /*微妙計時結束,計算訊息時間*/ gettimeofday(&end, NULL); allTime.messageTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; for (i = 0; i < MAX_RUN; i++) { /*微妙計時開始*/ gettimeofday(&start, NULL); /*微妙計時開始*/ gettimeofday(&allowstart, NULL); /*發:第一次握手*/ sendMessage(client, "First:Run !", 11); /*收:第二次握手*/ runData[MAXDATA] = receiveMessage(client); if (strcmp(runData, "Second:Run !") == 0) { /*發:第三次握手*/ sendMessage(client, "Third:Run !", 11); /*微妙計時結束,計算執行時間*/ gettimeofday(&allowend, NULL); allTime.allowTime[i] = 1000000 * (allowend.tv_sec - allowstart.tv_sec) + allowend.tv_usec - allowstart.tv_usec; allowSum = allowSum + allTime.allowTime[i]; /*執行時間大於週期時間,則直接執行執行*/ if (t >= T) { /*微妙計時開始*/ gettimeofday(&exestart, NULL); /*計時開始*/ startTime = clock(); exe(); /*計時結束*/ endTime = clock(); /*微妙計時結束,計算執行時間*/ gettimeofday(&exeend, NULL); allTime.exeTime[i] = 1000000 * (exeend.tv_sec - exestart.tv_sec) + exeend.tv_usec - exestart.tv_usec; exeSum = exeSum + allTime.exeTime[i]; /*微妙計時開始*/ gettimeofday(&calstart, NULL); /*服務端執行用時*/ serverTime_d = (double)(endTime - startTime); //printf("serverTime_d=%ld\n", serverTime_d); //printf("exeTime=%ld\n", allTime.exeTime[i] / 1000); serverTime_c_server = charChange(serverTime_d); sendMessage(client, serverTime_c_server, strlen(serverTime_c_server)); clientTime_c[MAXDATA] = receiveMessage(client); /*字串轉整形*/ serverTime_i = atoi(serverTime_c_server); //printf("Server's operation time is %d\n", serverTime_i); clientTime_i = atoi(clientTime_c); //printf("Client's operation time is %d\n", clientTime_i); t = compareTime(serverTime_i, clientTime_i); //printf("The whole system's operation time is %d\n\n", t); /*微妙計時結束,計算執行時間*/ gettimeofday(&calend, NULL); allTime.calTime[i] = 1000000 * (calend.tv_sec - calstart.tv_sec) + calend.tv_usec - calstart.tv_usec; calSum = calSum + allTime.calTime[i]; /*執行總時長小於週期時間,掛起*/ if (t <= T) { waitTime_0[i] = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000; Sleep(waitTime_0[i]); t = T; allTime.waitTime[i] = waitTime_0[i] * 1000; waitSum = waitSum + allTime.waitTime[i]; /*gettimeofday(&waitstart, NULL); waitTime = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000; Sleep(waitTime); t = T; gettimeofday(&waitend, NULL); allTime.waitTime[i] = 1000000 * (waitend.tv_sec - waitstart.tv_sec) + waitend.tv_usec - waitstart.tv_usec; waitSum = waitSum + allTime.waitTime[i];*/ } else { allTime.waitTime[i] = 0; } } } /*微妙計時結束,計算執行時間*/ gettimeofday(&end, NULL); allTime.runTime[i] = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; runSum = runSum + allTime.runTime[i]; } closesocket(server); WSACleanup(); printf("modeTime=%ld, connectTime=%ld, messageTime=%ld\n", allTime.modeTime, allTime.connectTime, allTime.messageTime); printf("allowTime=%ld, exeTime=%ld, calTime=%ld, waitTime=%ld\n\n", allowSum / MAX_RUN, exeSum / MAX_RUN, calSum / MAX_RUN, waitSum / MAX_RUN); //printf("runTime=%ld\n\n", runSum / MAX_RUN); } /*客戶端*/ else { /*微妙計時結束,計算連線時間*/ gettimeofday(&end, NULL); allTime.modeTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; /*微妙計時開始*/ gettimeofday(&start, NULL); /*啟動windows的socket服務,初始化WSA*/ WSAStartup(0x101, &wsaData); /*建立客戶端,初始化客戶端地址*/ memset((void*)&clientaddr, 0, sizeof(clientaddr)); client = creatSocket(); /*繫結IP和埠*/ clientaddr.sin_family = AF_INET; /*定義家族協議*/ clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); /*定義主機地址*/ clientaddr.sin_port = htons(PORT); /*定義主機埠*/ connentSocket(client, clientaddr); /*微妙計時結束,計算連線時間*/ gettimeofday(&end, NULL); allTime.connectTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; /*微妙計時開始*/ gettimeofday(&start, NULL); for (i = 0; i < MAX_MESSAGE; i++) { receiveMessage(client); sendMessage(client, "I'm ready too !", 15); } /*微妙計時結束,計算訊息時間*/ gettimeofday(&end, NULL); allTime.messageTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; /*檢驗執行許可指令並開始執行*/ for (i = 0; i < MAX_RUN; i++) /*改*/ { /*微妙計時開始*/ gettimeofday(&start, NULL); /*微妙計時開始*/ gettimeofday(&allowstart, NULL); /*收:第一次握手*/ runData[MAXDATA] = receiveMessage(client); if (strcmp(runData, "First:Run !") == 0) { /*發:第二次握手*/ sendMessage(client, "Second:Run !", 12); } /*收:第三次握手*/ runData[MAXDATA] = receiveMessage(client); /*微妙計時結束,計算執行時間*/ gettimeofday(&allowend, NULL); allTime.allowTime[i] = 1000000 * (allowend.tv_sec - allowstart.tv_sec) + allowend.tv_usec - allowstart.tv_usec; allowSum = allowSum + allTime.allowTime[i]; if (strcmp(runData, "Third:Run !") == 0) { /*執行時間大於週期時間,則直接執行執行*/ if (t >= T) { /*微妙計時開始*/ gettimeofday(&exestart, NULL); /*計時開始*/ startTime = clock(); exe(); /*計時結束*/ endTime = clock(); /*微妙計時結束,計算執行時間*/ gettimeofday(&exeend, NULL); allTime.exeTime[i] = 1000000 * (exeend.tv_sec - exestart.tv_sec) + exeend.tv_usec - exestart.tv_usec; exeSum = exeSum + allTime.exeTime[i]; /*微妙計時開始*/ gettimeofday(&calstart, NULL); /*客戶端執行用時*/ clientTime_d = (double)(endTime - startTime); clientTime_c_client = charChange(clientTime_d); sendMessage(client, clientTime_c_client, strlen(clientTime_c_client)); serverTime_c[MAXDATA] = receiveMessage(client); /*字串轉整形*/ serverTime_i = atoi(serverTime_c); //printf("Server's operation time is %d\n", serverTime_i); clientTime_i = atoi(clientTime_c_client); //printf("Client's operation time is %d\n", clientTime_i); t = compareTime(serverTime_i, clientTime_i); //printf("The whole system's operation time is %d\n\n", t); /*微妙計時結束,計算執行時間*/ gettimeofday(&calend, NULL); allTime.calTime[i] = 1000000 * (calend.tv_sec - calstart.tv_sec) + calend.tv_usec - calstart.tv_usec; calSum = calSum + allTime.calTime[i]; /*執行總時長小於週期時間,掛起*/ if (t <= T) { waitTime_0[i] = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000; Sleep(waitTime_0[i]); t = T; allTime.waitTime[i] = waitTime_0[i] * 1000; waitSum = waitSum + allTime.waitTime[i]; /*gettimeofday(&waitstart, NULL); waitTime = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000; Sleep(waitTime); t = T; gettimeofday(&waitend, NULL); allTime.waitTime[i] = 1000000 * (waitend.tv_sec - waitstart.tv_sec) + waitend.tv_usec - waitstart.tv_usec; waitSum = waitSum + allTime.waitTime[i];*/ } else { allTime.waitTime[i] = 0; } } } /*微妙計時結束,計算執行時間*/ gettimeofday(&end, NULL); allTime.runTime[i] = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; runSum = runSum + allTime.runTime[i]; } closesocket(client); WSACleanup(); printf("modeTime=%ld, connectTime=%ld, messageTime=%ld\n", allTime.modeTime, allTime.connectTime, allTime.messageTime); printf("allowTime=%ld, exeTime=%ld, calTime=%ld, waitTime=%ld\n\n", allowSum / MAX_RUN, exeSum / MAX_RUN, calSum / MAX_RUN, waitSum / MAX_RUN); //printf("runTime=%ld\n\n", runSum / MAX_RUN); } return allTime; } int main(void) { /*各種定義*/ struct Time pTime[MAX_MAIN]; int i, j, k, l; long int modeTimeMax, connectTimeMax, messageTimeMax, allowTimeMax, exeTimeMax, calTimeMax, waitTimeMax, runTimeMax; long int modeTimeSum, connectTimeSum, messageTimeSum, allowTimeSum, exeTimeSum, calTimeSum, waitTimeSum, runTimeSum; long int modeTimeAve, connectTimeAve, messageTimeAve, allowTimeAve, exeTimeAve, calTimeAve, waitTimeAve, runTimeAve; /*執行程式*/ for (i = 0; i < MAX_MAIN; i++) { pTime[i] = run(); } /*計算選擇模式的最大時間*/ for (j = 0, modeTimeMax = 0; j < MAX_MAIN; j++) { if (modeTimeMax < pTime[j].modeTime) { modeTimeMax = pTime[j].modeTime; } } /*計算連線的最大時間*/ for (j = 0, connectTimeMax = 0; j < MAX_MAIN; j++) { if (connectTimeMax < pTime[j].connectTime) { connectTimeMax = pTime[j].connectTime; } } /*計算髮送接收訊息的最大時間*/ for (j = 0, messageTimeMax = 0; j < MAX_MAIN; j++) { if (messageTimeMax < pTime[j].messageTime) { messageTimeMax = pTime[j].messageTime; } } /*計算三次握手的最大時間*/ for (k = 0, allowTimeMax = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { if (allowTimeMax < pTime[k].allowTime[l]) { allowTimeMax = pTime[k].allowTime[l]; } } } /*計算執行演算法的最大時間*/ for (k = 0, exeTimeMax = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { if (exeTimeMax < pTime[k].exeTime[l]) { exeTimeMax = pTime[k].exeTime[l]; } } } /*計算時間彙總的最大時間*/ for (k = 0, calTimeMax = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { if (calTimeMax < pTime[k].calTime[l]) { calTimeMax = pTime[k].calTime[l]; } } } /*計算等待的最大時間*/ for (k = 0, waitTimeMax = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { if (waitTimeMax < pTime[k].waitTime[l]) { waitTimeMax = pTime[k].waitTime[l]; } } } /*計算迴圈的最大時間*/ for (k = 0, runTimeMax = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { if (runTimeMax < pTime[k].runTime[l]) { runTimeMax = pTime[k].runTime[l]; } } } /*計算選擇模式的平均時間*/ for (j = 0, modeTimeSum = 0; j < MAX_MAIN; j++) { modeTimeSum += pTime[j].modeTime; } modeTimeAve = modeTimeSum / MAX_MAIN; /*計算連線的平均時間*/ for (j = 0, connectTimeSum = 0; j < MAX_MAIN; j++) { connectTimeSum += pTime[j].connectTime; } connectTimeAve = connectTimeSum / MAX_MAIN; /*計算髮送接收訊息的平均時間*/ for (j = 0, messageTimeSum = 0; j < MAX_MAIN; j++) { messageTimeSum += pTime[j].messageTime; } messageTimeAve = messageTimeSum / MAX_MAIN; /*計算執行演算法的平均時間*/ for (k = 0, allowTimeSum = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { allowTimeSum += pTime[k].allowTime[l]; } } allowTimeAve = allowTimeSum / (MAX_MAIN * MAX_RUN); /*計算執行演算法的平均時間*/ for (k = 0, exeTimeSum = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { exeTimeSum += pTime[k].exeTime[l]; } } exeTimeAve = exeTimeSum / (MAX_MAIN * MAX_RUN); /*計算時間彙總的平均時間*/ for (k = 0, calTimeSum = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { calTimeSum += pTime[k].calTime[l]; } } calTimeAve = calTimeSum / (MAX_MAIN * MAX_RUN); /*計算等待的平均時間*/ for (k = 0, waitTimeSum = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { waitTimeSum += pTime[k].waitTime[l]; } } waitTimeAve = waitTimeSum / (MAX_MAIN * MAX_RUN); /*計算迴圈的平均時間*/ for (k = 0, runTimeSum = 0; k < MAX_MAIN; k++) { for (l = 0; l < MAX_RUN; l++) { runTimeSum += pTime[k].runTime[l]; } } runTimeAve = runTimeSum / (MAX_MAIN * MAX_RUN); /*輸出結果*/ printf("modeTimeMax=%ld, modeTimeAve=%ld\n", modeTimeMax, modeTimeAve); printf("connectTimeMax=%ld, connectTimeAve=%ld\n", connectTimeMax, connectTimeAve); printf("messageTimeMax=%ld, messageTimeAve=%ld\n", messageTimeMax, messageTimeAve); printf("allowTimeMax=%ld, allowTimeAve=%ld\n", allowTimeMax, allowTimeAve); printf("exeTimeMax=%ld, exeTimeAve=%ld\n", exeTimeMax, exeTimeAve); printf("calTimeMax=%ld, calTimeAve=%ld\n", calTimeMax, calTimeAve); printf("waitTimeMax=%ld, waitTimeAve=%ld\n", waitTimeMax, waitTimeAve); //printf("runTimeMax=%ld, runTimeAve=%ld\n", runTimeMax, runTimeAve); Sleep(10000000000); return 0; }
收穫:
- 模式控制可以用BOOL來實現,比如
BOOL hasMsg = FALSE;
statement1
if (!hasMsg)
{
statement2
}
- “error LNK2019: 無法解析的外部符號”這個錯誤有可能是不同版本的vs之間不相容造成的,在當前版本的vs下重建一個專案,然後把程式碼複製過去,就可以解決這個問題
- 所有陣列,只有在定義時才能初始化,其他時候的初始化都是錯的