惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
爱范儿
爱范儿
V
Visual Studio Blog
Last Week in AI
Last Week in AI
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
博客园 - Franky
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
罗磊的独立博客
L
LangChain Blog
Jina AI
Jina AI
IT之家
IT之家
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页

博客园 - kingkoo

ReaHat7.6/7.7 最小化安装更新yum源 java程序员经常使用的Intellij Idea插件 NDK版本 下载地址 在Intellij IDEA下用X-debug调试PHP DMSFrame 之查询表达式用法(一) Wise 打包细节 将Centos的yum源更换为国内的阿里云(163)源 Centos下安装 .net Core运行程序 使用 Docker 一步搞定 ZooKeeper 集群的搭建 docker 安装与学习 maven中scope标签以及exclusions 记录 Centos MySQL数据库迁移详细步骤 Maven 本地仓库明明有jar包,pom文件还是报错解决办法 位与,位或,位异或运算符的理解 编程中位运算用法总结 消息中间件Notify和MetaQ-阿里中间件 DMSFrame 之SqlCacheDependency(二) DMSFrame 之SqlCacheDependency(一) DMSFrame 之简单用法(二)
C++ CompletionPort(完成端口)示例
kingkoo · 2016-11-30 · via 博客园 - kingkoo

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