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

  

posted @ 2016-11-30 10:08  kingkoo  阅读(841)  评论(0编辑  收藏  举报