win32 | WinSock2網路程式設計 | socket-tcp通訊
阿新 • • 發佈:2020-12-02
今天覆習了一下tcp通訊的實現,寫了寫程式碼。
簡單的總結一下:
伺服器作為監聽者的角色需要先建立伺服器socket套接字,然後使用bind繫結套接字和埠資訊等等,再建立用於連線客戶端的socket套接字,使用accept函式等待客戶端的連線並處理。
客戶端則只需要建立用於連線伺服器的socket套接字connect函式建立與遠端主機的連結就可以了。
同時需要注意的是錯誤的處理和關閉套接字等等。
伺服器:
1 #include<WinSock2.h> 2 #pragma comment(lib,"ws2_32.lib") 3 #include <stdio.h> 4#include <string.h> 5 6 7 8 int main(){ 9 WSADATA wsaData; // 初始化返回資訊結構體 10 WORD wVersion = MAKEWORD(2,2); // 製作版本號 11 SOCKET hServer; // 定義套接字控制代碼 12 if (WSAStartup(wVersion, &wsaData)){ //初始化 13 printf("initial failed"); 14 return 0;15 } 16 //in_addr addr; // ip地址結構體 17 //addr.s_addr = inet_addr("127.0.0.1"); // 轉化字串為32位整形ip地址 18 //char* lpszIp = inet_ntoa(addr); //整形轉化為字串形式 19 20 hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //tcp形式流式套接字 21 if (hServer == INVALID_SOCKET){ 22 printf("socket failed \n"); 23 } 24 sockaddr_in addrServer; 25 addrServer.sin_family = AF_INET; 26 addrServer.sin_port = htons(8888); // 指定埠 27 addrServer.sin_addr.s_addr = htonl(INADDR_ANY); //指定能訪問的ip 28 int nRet = bind(hServer, (sockaddr*)&addrServer, sizeof(addrServer)); 29 if (nRet == SOCKET_ERROR){ 30 printf("bind error \n"); 31 closesocket(hServer); 32 WSACleanup(); 33 return 0; 34 } 35 //進行監聽 36 nRet = listen(hServer,5); //最多監聽5個 37 printf("start listening ... \n"); 38 if (nRet == SOCKET_ERROR){ 39 printf("listen error \n"); 40 closesocket(hServer); 41 WSACleanup(); 42 return 0; 43 } 44 45 //接收客戶端請求 46 SOCKET hClient; 47 sockaddr_in addrClient; 48 int nLen = sizeof(addrClient); 49 hClient = accept(hServer,(sockaddr *)&addrClient, &nLen); // ?建立監聽控制代碼,直到接收到請求 50 if (hClient == INVALID_SOCKET){ 51 printf("accept error \n"); 52 closesocket(hServer); 53 WSACleanup(); 54 return 0; 55 } 56 printf("Get a connect! \n"); 57 send(hClient, "helllllllooooooo!!!!!!",sizeof("helllllllooooooo!!!!!!"), 0); 58 59 char szBuf[255]; 60 //迴圈接收客戶端資料 61 while (1) 62 { 63 memset(szBuf, 0, sizeof(szBuf)); // 清空緩衝區 64 nRet = recv(hClient, szBuf,sizeof(szBuf),0); 65 if (nRet == SOCKET_ERROR){ 66 printf("recv error \n"); 67 closesocket(hClient); 68 closesocket(hServer); 69 WSACleanup(); 70 return 0; 71 } 72 73 char sPrint[sizeof(szBuf)]; 74 sprintf(sPrint, "IP:%s, recv msg: %s ",inet_ntoa(addrClient.sin_addr),szBuf);//格式化字串 75 printf(sPrint); 76 if(strcmp(szBuf, "close") == 0){ // 檢測退出 77 nRet = send(hClient,"close",strlen("close"), 0); 78 break; 79 } 80 else{ 81 //接收到資料 82 sprintf(sPrint, "the server has recved your msg: %s ", szBuf); 83 nRet = send(hClient,sPrint,strlen(sPrint), 0); 84 if (nRet == SOCKET_ERROR){ 85 printf("send err \n"); 86 closesocket(hClient); 87 closesocket(hServer); 88 WSACleanup(); 89 return 0; 90 } 91 } 92 93 94 } 95 closesocket(hClient); 96 closesocket(hServer); 97 WSACleanup(); 98 99 return 0; 100 }
客戶端:
1 #include<WinSock2.h> 2 #pragma comment(lib,"ws2_32.lib") 3 #include <stdio.h> 4 #include <string.h> 5 6 7 8 int main(){ 9 WSADATA wsaData; // 初始化返回資訊結構體 10 WORD wVersion = MAKEWORD(2,2); // 製作版本號 11 SOCKET hClient; // 定義套接字控制代碼 12 if (WSAStartup(wVersion, &wsaData)){ //初始化 13 printf("initial failed"); 14 return 0; 15 } 16 17 hClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //tcp形式流式套接字 18 if (hClient == INVALID_SOCKET){ 19 printf("socket failed \n"); 20 } 21 22 sockaddr_in addrServer; 23 addrServer.sin_family = AF_INET; 24 addrServer.sin_port = htons(8888); // 指定埠 25 addrServer.sin_addr.s_addr = inet_addr("192.168.56.101"); //指定要連線的ip 26 //建立連線 27 int nRet = connect(hClient,(sockaddr*)&addrServer, sizeof(addrServer)); 28 if (nRet == SOCKET_ERROR){ 29 printf("connect error \n"); 30 closesocket(hClient); 31 WSACleanup(); 32 return 0; 33 } 34 printf("connect successsssss!!!\n"); 35 36 char szBuf[255]; 37 //迴圈接收客戶端資料 38 while (1) 39 { 40 memset(szBuf, 0, sizeof(szBuf)); // 清空緩衝區 41 nRet = recv(hClient, szBuf,sizeof(szBuf),0); 42 if (nRet == SOCKET_ERROR){ 43 printf("recv error \n"); 44 closesocket(hClient); 45 WSACleanup(); 46 return 0; 47 } 48 49 char sPrint[sizeof(szBuf)]; 50 sprintf(sPrint, "recv msg: %s ",szBuf);//格式化字串 51 printf(sPrint); 52 if(strcmp(szBuf, "close") == 0){ // 檢測退出 53 nRet = send(hClient,"close",strlen("close"), 0); 54 break; 55 } 56 else{ 57 //接收到資料 58 if (strcmp(szBuf, "helllllllooooooo!!!!!!") == 0){ 59 send(hClient, "wow", sizeof("wow"),0); 60 } 61 } 62 63 64 } 65 closesocket(hClient); 66 WSACleanup(); 67 68 return 0; 69 }