C++ CompletionPort(完成端口)示例
ECHO客户端
#include <WINSOCK2.H> #include <stdio.h> #define SERVER_ADDRESS "127.0.0.1" //服务器地址 #define PORT 5150 //端口 #define MSGSIZE 1024 //信息缓冲大小 #pragma comment(lib, "ws2_32.lib") int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; SOCKET sClient; SOCKADDR_IN server; char szMessage[MSGSIZE]; int ret; // Initialize Windows socket library WSAStartup(0x0202, &wsaData); // Create client socket sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Connect to server memset(&server, 0, sizeof(SOCKADDR_IN)); server.sin_family = AF_INET; server.sin_addr.S_un.S_addr = inet_addr(SERVER_ADDRESS); server.sin_port = htons(PORT); connect(sClient, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)); printf("client is contect\r\n"); while (TRUE) { printf("Send:"); gets(szMessage); // Send message send(sClient, szMessage, strlen(szMessage), 0); // Receive message ret = recv(sClient, szMessage, MSGSIZE, 0); szMessage[ret] = '\0'; printf("Received [%d bytes]: '%s'\n", ret, szMessage); } // Clean up closesocket(sClient); WSACleanup(); return 0; }
Echo服务端代码:
#include <WINSOCK2.H> #include <stdio.h> #define PORT 5150 //端口 #define MSGSIZE 1024 //信息缓冲大小 #pragma comment(lib, "ws2_32.lib") typedef enum { RECV_POSTED }OPERATION_TYPE; typedef struct { WSAOVERLAPPED overlap; WSABUF Buffer; char szMessage[MSGSIZE]; DWORD NumberOfBytesRecvd; DWORD Flags; OPERATION_TYPE OperationType; }COverLapped, *p_COverLapped; DWORD WINAPI WorkerThread(LPVOID); int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; SOCKET m_wListen = INVALID_SOCKET; //监听句柄 SOCKET m_wSocket = INVALID_SOCKET; // SOCKADDR_IN local, client; DWORD i, dwThreadId; int iaddrSize = sizeof(SOCKADDR_IN); HANDLE CompletionPort = INVALID_HANDLE_VALUE; SYSTEM_INFO systeminfo; p_COverLapped pOverLapped = NULL; // Initialize Windows Socket library WSAStartup(0x0202, &wsaData); // Create completion port CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); // Create worker thread GetSystemInfo(&systeminfo); for (i = 0; i < systeminfo.dwNumberOfProcessors; i++) { CreateThread(NULL, 0, WorkerThread, CompletionPort, 0, &dwThreadId); } // Create listening socket m_wListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Bind local.sin_addr.S_un.S_addr = htonl(INADDR_ANY); local.sin_family = AF_INET; local.sin_port = htons(PORT); bind(m_wListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN)); // Listen listen(m_wListen, 3); while (TRUE) { // Accept a connection m_wSocket = accept(m_wListen, (struct sockaddr *)&client, &iaddrSize); printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); //初始化对象 //CSocketItem * pSocketItem = new CSocketItem(); //pSocketItem->Attach(m_wSocket, client.sin_addr.S_un.S_addr); // Associate the newly arrived client socket with completion port CreateIoCompletionPort((HANDLE)m_wSocket, CompletionPort, (DWORD)m_wSocket, 0); // Launch an asynchronous operation for new arrived connection pOverLapped = (p_COverLapped)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COverLapped)); pOverLapped->Buffer.len = MSGSIZE; pOverLapped->Buffer.buf = pOverLapped->szMessage; pOverLapped->OperationType = RECV_POSTED; WSARecv(m_wSocket, &pOverLapped->Buffer, 1, &pOverLapped->NumberOfBytesRecvd, &pOverLapped->Flags, &pOverLapped->overlap, NULL); } PostQueuedCompletionStatus(CompletionPort, 0xFFFFFFFF, 0, NULL); CloseHandle(CompletionPort); closesocket(m_wListen); WSACleanup(); return 0; } DWORD WINAPI WorkerThread(LPVOID CompletionPortID) { HANDLE CompletionPort = (HANDLE)CompletionPortID; DWORD dwBytesTransferred; SOCKET sClient; p_COverLapped pOverLapped = NULL; while (TRUE) { GetQueuedCompletionStatus(CompletionPort, &dwBytesTransferred, (PULONG_PTR)&sClient, (LPOVERLAPPED *)&pOverLapped, INFINITE); if (dwBytesTransferred == 0xFFFFFFFF) { return 0; } if (pOverLapped->OperationType == RECV_POSTED) { if (dwBytesTransferred == 0) { // Connection was closed by client closesocket(sClient); HeapFree(GetProcessHeap(), 0, pOverLapped); } else { pOverLapped->szMessage[dwBytesTransferred] = '\0'; send(sClient, pOverLapped->szMessage, dwBytesTransferred, 0); // Launch another asynchronous operation for sClient memset(pOverLapped, 0, sizeof(COverLapped)); pOverLapped->Buffer.len = MSGSIZE; pOverLapped->Buffer.buf = pOverLapped->szMessage; pOverLapped->OperationType = RECV_POSTED; WSARecv(sClient, &pOverLapped->Buffer, 1, &pOverLapped->NumberOfBytesRecvd, &pOverLapped->Flags, &pOverLapped->overlap, NULL); } } } return 0; }
千人.NET交流群:18362376,因为有你,代码变得更简单,加群请输入cnblogs