參考文章:1.Windows Socket編程2.揭開Socket編程的面紗
Windows下Socket TCP編程的大體流程如下: Server端 1、初始化Windows Socket庫. 2、建立Socket. 3、綁定Socket. 4、監聽. 5、Accept. 6、接發資料. Client端 1、初始化Windows Socket庫. 2、建立Socket. 3、串連. 4、接發資料.
以下樣本中,服務端接受用戶端串連,並建立線程接收資料並輸出。 用戶端串連服務端,並向伺服器端發送資料。 即非常簡單的:Client端向Server端發送資料,Server端為每個Client端串連建立一個線程以接收資料並輸出,串連結束則結束對應線程。
Server.cpp
#include <iostream>#include <windows.h>#include <process.h>using namespace std;#pragma comment(lib, "Ws2_32.lib")#define PORT_NO 6000#define BACKLOG 10unsigned __stdcall clientThrd(void *lpParam){SOCKET sockClient = (SOCKET)lpParam;int ret = 0;char recvBuffer[MAX_PATH] = {0};// 接收資料------while (1){memset(recvBuffer, 0, sizeof(recvBuffer));ret = recv(sockClient, recvBuffer, sizeof(recvBuffer), 0);if (ret == 0){cout << "Connection has been gracefully closed." << endl;break;}else if (ret == SOCKET_ERROR) {cout << "Connection has been closed ungracefully." << endl;break;}cout << "Receive Data from Client:" << recvBuffer << endl;}closesocket(sockClient);return 0;}int main(int argc, char* argv[]){WSADATA wsaData;int ret;WORD wVersionRequested = MAKEWORD(2, 2);SOCKET sockSrv, sockConn;SOCKADDR_IN addrSrv, addrClient;HANDLE hThread = NULL;// 初始化Windows Socket------ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0) {cout << "WSAStartup() failed:" << WSAGetLastError() << endl;return -1;}// 建立Socket------sockSrv = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == sockSrv){cout << "socket() failed:" << WSAGetLastError() << endl;WSACleanup();return -1;}addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT_NO);// Bind Socket------ret = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (SOCKET_ERROR == ret){cout << "bind() failed:" << WSAGetLastError() << endl;closesocket(sockSrv);WSACleanup();return -1;}// 監聽------ret = listen(sockSrv, BACKLOG);if (SOCKET_ERROR == ret){cout << "listen() failed:" << WSAGetLastError() << endl;closesocket(sockSrv);WSACleanup();return -1;}cout<< "Server started......" << endl;// Accept------int len=sizeof(SOCKADDR);while(1){sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);if (INVALID_SOCKET == sockConn){cout << "accept() failed:" << WSAGetLastError() << endl;break;}hThread = (HANDLE)_beginthreadex(NULL, 0, clientThrd, (void*)sockConn, 0, NULL);if (hThread == 0){cout << "_beginthreadex() failed." << endl;break;}CloseHandle(hThread);}// 清理資源------closesocket(sockSrv);WSACleanup();cout << "exit..." << endl;return 0;}
Client.cpp
#include <iostream>#include <windows.h>using namespace std;#pragma comment(lib, "Ws2_32.lib")#define PORT_NO 6000#define SRV_IP_ADDR "127.0.0.1"int main(int argc, char* argv[]){int ret;WSADATA wsaData;WORD wVersionRequested = MAKEWORD(2, 2);SOCKET sockClient;SOCKADDR_IN addrSrv;// 初始化Windows Socket------ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0) {cout << "WSAStartup() failed:" << WSAGetLastError() << endl;return -1;} // 建立Socket------sockClient = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == sockClient){cout << "socket() failed:" << WSAGetLastError() << endl;WSACleanup();return -1;}addrSrv.sin_addr.S_un.S_addr = inet_addr(SRV_IP_ADDR);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT_NO);// 串連------ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (SOCKET_ERROR == ret){cout << "connect() failed:" << WSAGetLastError() << endl;closesocket(sockClient);WSACleanup();return -1;}else{cout << "connect() successfully." << endl;}// 發送資料------char sendBuf[MAX_PATH] = {0};while (1){cin.getline(sendBuf, sizeof(sendBuf));if (strcmp(sendBuf, "exit") == 0){break;}ret = send(sockClient, sendBuf, strlen(sendBuf)+1, 0);if (SOCKET_ERROR == ret){cout << "send() failed:" << WSAGetLastError() << endl;closesocket(sockClient);WSACleanup();return -1;}}// 清理資源-------closesocket(sockClient);WSACleanup();cout << "exit..." << endl;return 0;}