C++ CompletionPort(完成端口)示例

时间:2023-03-08 20:42:52

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;
}