1.Windows socket 函數介紹
2.程序
服務器程序
#include <stdlib.h> #include <stdio.h> #include <WinSock2.h> #pragma comment(lib,"Ws2_32.lib ") int main() { WSADATA wsaData; struct sockaddr_in servAddr; struct sockaddr_in cliAddr; if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { printf("Error:RequestWindowsSocketLibrary failed!\n"); return 0; } /* 設置IP地址 */ memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //綁定本機IP //servAddr.sin_addr.s_addr = inet_addr("192.168.1.53"); /* 設置端口 */ servAddr.sin_family = AF_INET; servAddr.sin_port = htons(3000); //端口為3000 /* 創建套接服務字 */ SOCKET serverSocket; serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket == INVALID_SOCKET) { printf("Error:CreatServerSocket failed!\n"); return 0; } /* 綁定服務器套接字 */ if (bind(serverSocket, (sockaddr*)&servAddr, sizeof(sockaddr)) == SOCKET_ERROR) { printf("ERROR:Bind failed!\n"); return 0; } /* 監聽端口 */ if (listen(serverSocket, 20) == SOCKET_ERROR) { closesocket(serverSocket); WSACleanup(); printf("ERROR:Listen failed!\n"); return 0; } printf("linstening:%dport...\n", ntohs(servAddr.sin_port)); /* 阻塞方式等待accept */ int len = sizeof(cliAddr); SOCKET clientSocket; clientSocket = accept(serverSocket, (sockaddr*)&cliAddr, &len); printf("Connected:%s \r\n", inet_ntoa(cliAddr.sin_addr)); /* 接受消息 */ char recvBuf[100] = { 0 }; recv(clientSocket, recvBuf, sizeof(recvBuf), 0); /* 發送消息 */ send(clientSocket, recvBuf, 100, NULL); closesocket(clientSocket); WSACleanup(); system("pause"); return 1; }
客戶端代碼
#include "stdlib.h" #include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") //加載 ws2_32.dll int main() { //初始化DLL //主版本號(低字節)為2,副版本號為2,返回 0x0202 WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; //WSAStartup() 函數執行成功后,會將與 ws2_32.dll 有關的信息寫入 WSAData 結構體變量 //(只需關注前兩個成員即可) if (WSAStartup(sockVersion, &wsaData) != 0) return 0; //創建套接字,socket() 函數用來創建套接字,確定套接字的各種屬性 //IPv4 地址、面向連接的數據傳輸方式、TCP 傳輸協議 SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //向服務器發起請求,將創建的套接字與IP地址 101.76.220.219、端口 3000 綁定: sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; //32位IP地址,s_addr 是一個整數(unsigned long),而IP地址是一個字符串, //所以需要 inet_addr() 函數進行轉換 sockAddr.sin_addr.s_addr = inet_addr("101.76.218.229"); //16位的端口號,端口號需要用 htons() 函數轉換,0~1023 的端口一般由系統分配給特定的服務程序, //盡量在 1024~65536 之間分配端口號。 sockAddr.sin_port = htons(3000); //強制類型轉換,服務器端要用 bind() 函數將套接字與特定的IP地址和端口綁定起來, //只有這樣,流經該IP地址和端口的數據才能交給套接字處理 while (connect(sock, (SOCKADDR*)& sockAddr, sizeof(SOCKADDR)) == SOCKET_ERROR) { printf("連接失敗\n"); Sleep(1000); } printf("成功連接到服務器!\n"); char sendBuf[100] = {"Hello World"}; send(sock, sendBuf, 100, NULL); char recvBuf[100] = { 0 }; recv(sock, recvBuf, 100, 0); closesocket(sock); WSACleanup(); for (int i = 0; i < 12; i++) { printf("%c",recvBuf[i]); } system("pause"); return 1; }