- 浏览: 328611 次
最新评论
-
riki:
D 语言学习交流群 264617728, 欢迎加入
D语言真相 The Case for D(1-5) -
exploder:
请教,如果使用D2进行wxD编译呢?
编译WxD0.16 -
blue_halo:
那如何解决呢????????
不能每次都用别的打开存成utf- ...
pyDev 中输入中文问题 -
funxue:
请教楼主
Error: undefined identifie ...
D语言版本的华容道 -
litsen:
在配置ms sqlserver的过程中遇到些问题,从Googl ...
安全第一,在sql server和client之间配置ssl连接
在WindowsNT平台上,最具有伸缩性和吞吐量的网络服务器程序都使用了完成端口。为了在D中使用完成端口,我写了这个简单的例子。希望大家指正!
在DMD1.020-1.022,WindowsXP,编译测试通过。
没有使用std.socket,因为std里面的socket实现不能使用重叠IO。
D 代码
- // D Program Language IOCP
- // write by ideage@gmail.com
- // complie: dmd ic ws2_32.lib
- import std.c.windows.windows, std.c.windows.winsock;
- import std.string, std.stdint, std.c.string, std.c.stdlib;
- import std.stdio;
- import std.thread;
- alias HANDLE WSAEVENT;
- alias OVERLAPPED WSAOVERLAPPED;
- alias OVERLAPPED* LPWSAOVERLAPPED;
- alias OVERLAPPED* POVERLAPPED, LPOVERLAPPED;
- struct GUID {
- align(1):
- DWORD Data1;
- WORD Data2;
- WORD Data3;
- BYTE Data4[8];
- }
- struct WSAPROTOCOLCHAIN {
- int ChainLen;
- DWORD[7] ChainEntries;
- }
- alias WSAPROTOCOLCHAIN* LPWSAPROTOCOLCHAIN;
- const WSAPROTOCOL_LEN = 255;
- const ERROR_IO_PENDING = 997;
- struct WSAPROTOCOL_INFOW {
- DWORD dwServiceFlags1;
- DWORD dwServiceFlags2;
- DWORD dwServiceFlags3;
- DWORD dwServiceFlags4;
- DWORD dwProviderFlags;
- GUID ProviderId;
- DWORD dwCatalogEntryId;
- WSAPROTOCOLCHAIN ProtocolChain;
- int iVersion;
- int iAddressFamily;
- int iMaxSockAddr;
- int iMinSockAddr;
- int iSocketType;
- int iProtocol;
- int iProtocolMaxOffset;
- int iNetworkByteOrder;
- int iSecurityScheme;
- DWORD dwMessageSize;
- DWORD dwProviderReserved;
- WCHAR[WSAPROTOCOL_LEN+1] szProtocol;
- }
- alias WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFOW;
- const WSA_FLAG_OVERLAPPED = 0x01;
- struct WSABUF {
- uint len;
- char* buf;
- }
- struct SOCKADDR {
- ushort sa_family;
- char[14] sa_data;
- }
- alias SOCKADDR* PSOCKADDR, LPSOCKADDR;
- alias WSABUF* LPWSABUF;
- alias uint GROUP;
- extern(Windows)
- {
- alias void function(DWORD, DWORD, LPWSAOVERLAPPED, DWORD) LPWSAOVERLAPPED_COMPLETION_ROUTINE;
- SOCKET WSASocketW(int, int, int, LPWSAPROTOCOL_INFOW, GROUP, DWORD);
- bool GetQueuedCompletionStatus(HANDLE, PDWORD, PDWORD, LPOVERLAPPED*, DWORD);
- HANDLE CreateIoCompletionPort(HANDLE, HANDLE, DWORD, DWORD);
- int WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
- int WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
- }
- alias WSASocketW WSASocket;
- // Maximum Buffer Size
- const int BUFFERSIZE = 128;
- enum IO_OPERATION
- { ACCEPT,READ,WRITE };
- struct PIO_DATA
- {
- WSAOVERLAPPED ol;
- char Buffer[BUFFERSIZE];
- WSABUF wsabuf;
- int nTotalBytes;
- int nSentBytes;
- IO_OPERATION opCode;
- SOCKET activeSocket;
- }
- int max_ThreadCount;
- HANDLE iocpHandle = INVALID_HANDLE_VALUE;
- SOCKET serverSock;
- int WorkerThread (void * context)
- {
- LPWSAOVERLAPPED lpol = null;
- PIO_DATA* lpIOContext = null;
- WSABUF buffSend;
- uint dwRecvNumBytes = 0;
- uint dwSendNumBytes = 0;
- uint dwFlags = 0;
- uint dwIoSize = 0;
- bool bSuccess = false;
- int nRet = 0;
- while( 1 ) {
- void * lpCompletionKey = null;
- bSuccess = GetQueuedCompletionStatus(iocpHandle, &dwIoSize,cast(LPDWORD)&lpCompletionKey,cast(LPOVERLAPPED *)&lpol, INFINITE);
- if( !bSuccess )
- {
- writefln("GetQueuedCompletionStatus() failed: %s.",GetLastError());
- break;
- }
- lpIOContext = cast(PIO_DATA * )lpol;
- if(dwIoSize == 0) //socket closed?
- {
- writefln("ClientSocket Disconnect!" );
- closesocket(lpIOContext.activeSocket);
- // delete lpIOContext;
- continue;
- }
- if(lpIOContext.opCode == IO_OPERATION.READ) // a read operation complete
- {
- char[] s = "Echo:" ~ std.string.toString(lpIOContext.wsabuf.buf);
- lpIOContext.wsabuf.buf = std.string.toStringz(s);
- lpIOContext.nTotalBytes = lpIOContext.wsabuf.len;
- lpIOContext.nSentBytes = 0;
- lpIOContext.opCode = IO_OPERATION.WRITE;
- dwFlags = 0;
- nRet = WSASend(
- lpIOContext.activeSocket,
- &lpIOContext.wsabuf, 1, &dwSendNumBytes,
- dwFlags,
- &(lpIOContext.ol) , null);
- if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError()) )
- {
- writefln("1.WASSend Failed,Ret:%s." ,WSAGetLastError() );
- closesocket(lpIOContext.activeSocket);
- continue;
- }
- }
- else if(lpIOContext.opCode == IO_OPERATION.WRITE) //a write operation complete
- {
- lpIOContext.nSentBytes += dwIoSize;
- dwFlags = 0;
- if( lpIOContext.nSentBytes < lpIOContext.nTotalBytes ) {
- lpIOContext.opCode = IO_OPERATION.WRITE;
- // A Write operation has not completed yet, so post another
- // Write operation to post remaining data.
- buffSend.buf = lpIOContext.Buffer.ptr + lpIOContext.nSentBytes; //offset.
- buffSend.len = lpIOContext.nTotalBytes - lpIOContext.nSentBytes;
- nRet = WSASend (lpIOContext.activeSocket,
- &buffSend, 1, &dwSendNumBytes,
- dwFlags,
- &(lpIOContext.ol), null);
- if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError()) ) {
- writefln("2.WASSend Failed,Ret:%s.",WSAGetLastError());
- closesocket(lpIOContext.activeSocket);
- continue;
- }
- }
- else
- {
- // Write operation completed, so post Read operation.
- lpIOContext.opCode = IO_OPERATION.READ;
- dwRecvNumBytes = 0;
- dwFlags = 0;
- lpIOContext.wsabuf.buf = lpIOContext.Buffer.ptr,
- lpIOContext.ol.Internal = 0;
- lpIOContext.ol.InternalHigh = 0;
- lpIOContext.ol.Offset = 0;
- lpIOContext.ol.OffsetHigh = 0;
- lpIOContext.ol.hEvent = null;
- lpIOContext.wsabuf.len = BUFFERSIZE;
- nRet = WSARecv(
- lpIOContext.activeSocket,
- &lpIOContext.wsabuf, 1, &dwRecvNumBytes,
- &dwFlags,
- &lpIOContext.ol, null);
- if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError()) ) {
- writefln("1.WASRecv Failed,Ret:%s.",WSAGetLastError() );
- closesocket(lpIOContext.activeSocket);
- continue;
- }
- }
- }
- }
- return 0;
- }
- int main ()
- {
- { // Init winsock2.2
- WSADATA wsaData;
- int retVal = -1;
- if( (retVal = WSAStartup(0x2020, &wsaData)) != 0 ) {
- writefln("WSAStartup Failed,Ret: %s" ,retVal);
- return 1;
- }
- }
- writefln("WSAStartup Init OK!" );
- { //Create socket
- serverSock = WSASocket(AF_INET,SOCK_STREAM, IPPROTO_TCP, null,0,WSA_FLAG_OVERLAPPED);
- if( serverSock == INVALID_SOCKET ) {
- writefln("Server Socket Creation Failed,Ret:%s." , WSAGetLastError() );
- return 1;
- }
- }
- writefln("Create socket OK!" );
- { //bind
- sockaddr_in service;
- service.sin_family = AF_INET;
- service.sin_addr.s_addr = htonl(INADDR_ANY);
- service.sin_port = htons(9001);
- int retVal = bind(serverSock,cast(sockaddr *)&service,service.sizeof);
- if( retVal == SOCKET_ERROR ) {
- writefln("Server Soket Bind Failed,Ret:%s." , WSAGetLastError() );;
- return 1;
- }
- }
- writefln("Binding ServerSocket OK!" );
- { //listen
- int retVal = listen(serverSock, 8);
- if( retVal == SOCKET_ERROR ) {
- writefln("Server Socket Listen Failed,Ret:%s." , WSAGetLastError() );;
- return 1;
- }
- }
- writefln("ServerSocket listen OK!" );
- //create iocp & binding serverSocket to iocp
- { // Create IOCP
- max_ThreadCount = 1 * 2;
- iocpHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE,null,0,max_ThreadCount);
- if (iocpHandle == null) {
- writefln("CreateIoCompletionPort() Failed,Ret:%s." , GetLastError() );
- return 1;
- }
- if (CreateIoCompletionPort(cast(HANDLE)serverSock,iocpHandle,0,0) == null){
- writefln("Binding Server Socket to IO Completion Port Failed,Ret:%s." , GetLastError() );
- return 1;
- }
- }
- writefln("Create IOCP & binding ServerSocket to IOCP OK!" );
- {
- Thread worker = new Thread(&WorkerThread, cast(void *)0);
- worker.start();
- }
- writefln("Create Worker threads OK, Waitting Client Connect..." );
- { //accept new connection
- while(1)
- {
- SOCKET clientsock = accept( serverSock, null, null );
- if(clientsock == SOCKET_ERROR) break;
- writefln("Client connected." );
- { //diable buffer to improve performance
- int nZero = 0;
- setsockopt(clientsock, SOL_SOCKET, SO_SNDBUF, cast(char *)&nZero, nZero.sizeof);
- }
- //binding ClientSocket to IOCP
- if (CreateIoCompletionPort(cast(HANDLE)clientsock,iocpHandle,0,0) == null){
- writefln("Binding Client Socket to IO Completion Port Failed,Ret:%s." , GetLastError() );
- closesocket(clientsock);
- }
- else {
- writefln("binding ClientSocket to IOCP OK!" );
- //post a recv request
- PIO_DATA data;
- data.opCode = IO_OPERATION.READ;
- data.nTotalBytes = 0;
- data.nSentBytes = 0;
- data.wsabuf.buf = data.Buffer.ptr;
- data.wsabuf.len = data.Buffer.sizeof;
- data.activeSocket = clientsock;
- uint dwRecvNumBytes=0,dwFlags=0;
- int nRet = WSARecv(clientsock,&data.wsabuf, 1, &dwRecvNumBytes,&dwFlags,&data.ol, null);
- if(nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError())){
- writefln("3.WASRecv Failed,Ret:%s." , WSAGetLastError() );;
- closesocket(clientsock);
- //delete data;
- }
- writefln("Post a recv request IOCP OK!" );
- }
- }
- }
- //close & Cleanup
- closesocket(serverSock);
- WSACleanup();
- return 0;
- }
评论
9 楼
ahadf
2007-10-22
"iocp的使用例子(哪怕是C方式的)在dsource上都找不到一个,仅此一条ideage的做法就值得称道."
---不想抬杠,不过偶手边的资料有5,6本书上都有类似的。网上一搜IOCP更是一大把。也许写个boost.asio D 语言简化版本还比较有价值。
---不想抬杠,不过偶手边的资料有5,6本书上都有类似的。网上一搜IOCP更是一大把。也许写个boost.asio D 语言简化版本还比较有价值。
8 楼
h_rain
2007-10-22
不错了.都这个样子了,进行封装也很简单了.
如果需要一个好的封装,需要考虑一些方面:IOCP句柄与状态查询的封装;线程的完善处理("逻辑"暂停,启动...);Socket句柄的重叠IO操作封装等;
如果想要一个完整的封装,这些东西的处理其实还是很复杂的.
如果需要一个好的封装,需要考虑一些方面:IOCP句柄与状态查询的封装;线程的完善处理("逻辑"暂停,启动...);Socket句柄的重叠IO操作封装等;
如果想要一个完整的封装,这些东西的处理其实还是很复杂的.
7 楼
tomqyp
2007-10-22
iocp的使用例子(哪怕是C方式的)在dsource上都找不到一个,仅此一条ideage的做法就值得称道。
6 楼
ahadf
2007-10-22
偶还是要说,又没用到D的特性,又没用到D的库,用C不挺好,为啥还要用D写呢?演示?这种程序书上网上一抓一大把,学C的比学D的人多多了,直接copy下来看的人指不定还多些。
5 楼
ideage
2007-10-22
这个例子关键是演示了IOCP在D语言中的应用:过程,方法。
已经写的IOCP的类,用在公司的程序,不能公开
已经写的IOCP的类,用在公司的程序,不能公开
4 楼
dayn9
2007-10-22
这只能说是批着D马甲的C程序吧?
oldrev老大,这点我持有异议。D也应该是多范式的语言,不能只有OO,OB,GP,否则会损失潜在用户,SP范式恰恰是用户最大的群体。
oldrev老大,这点我持有异议。D也应该是多范式的语言,不能只有OO,OB,GP,否则会损失潜在用户,SP范式恰恰是用户最大的群体。
3 楼
ahadf
2007-10-21
我还以为是一个IOCP的类。。。
2 楼
oldrev
2007-10-21
这只能说是批着D马甲的C程序吧?
1 楼
tomqyp
2007-10-20
收藏~
发表评论
-
最近抽空翻译了D语言实用入门教程
2018-04-20 10:42 912最近抽空翻译了D语言实用入门教程 地址在Github,供初 ... -
编译WxD0.16
2011-09-27 18:09 1733wx我在Python环境下用了 ... -
简单看了下DGui
2011-09-26 10:39 2299很久没有写代码了。。。。 怀念往日不如今天行动。生疏了 ... -
支持中文录入的harmonia
2010-08-16 22:40 1049harmonia界面很方便,发现不能录入中文.Patch一下. ... -
控制台得到密码不回显
2009-09-18 22:37 1280看到坛子有人问“在D或C下如何实现输入单个字符不回显?可能的应 ... -
D资源文件调用
2009-08-09 01:36 1075终于成功了。 资源文件太可爱,竟然可以如此。按名称进行 ... -
The Case for D中英文版PDF下载
2009-06-19 10:27 1418The Case for D 在网站上浏览不方便的,有了PD ... -
D语言真相 The Case for D(1-5)
2009-06-17 09:52 4930D语言真相 Andrei Alexandre ... -
The Case for D
2009-06-16 22:50 2319The Case for D Andrei Alexan ... -
Python嵌入D
2009-06-12 11:37 2001所有的嵌入都研究了一个遍。发现嵌入Python挺好,试试。 ... -
实用的DFL注册表
2009-05-27 09:09 1042应用中要用到注册表.DFL里面有. 参照了文档,写了一 ... -
DFL 2.027,1.041,2,3编译
2009-04-07 17:59 1615注:DFL已经更新,http://www.dprogrammi ... -
D2.0的字符串
2009-04-07 08:28 1394D2.0的字符串增加了常量,不变量和变量.在很大程度上增加了语 ... -
D语言编译器DMD开源了!
2009-03-05 19:56 3523自从1999年12月,Walter设计开发D语言以来,D语 ... -
D语言现状From2007
2009-03-02 15:32 1080I'm sure this was brought up in ... -
D语言GUI库简单比较
2009-02-20 15:25 3269通过对一些D语言可以使用的GUI进行比较,对初学者有个借 ... -
D语言脚本引擎简单比较
2009-02-19 14:38 1842经过长期的测试,使用,扩展代码编写,比较了D中可以使用的几种脚 ... -
D语言编译器开始支持Mac OSX
2009-02-15 18:25 1183D语言编译器开始支持Mac OSX。 D语言历经10年的发 ... -
触发DFL中的ComboBox控件的键盘事件
2009-02-06 12:04 1212class ComboxKeyDownFilter:IMess ... -
DFL分析(四)伟大的结构
2008-12-25 00:08 1434每个程序都有很多的代码编织而成.为了获得最大的兼容性,你要从容 ...
相关推荐
在“易语言IOCP完成端口源码”中,我们可以看到如何利用易语言这一国产编程语言来实现IOCP技术。易语言以其独特的汉语编程语法,降低了编程的门槛,使得开发者能更直观地理解代码逻辑。 IOCP的实现过程通常包括以下...
本文将深入探讨IOCP完成端口模型,并通过具体例子来阐述其工作原理和实现方法。 IOCP是Windows操作系统提供的一种高度优化的异步I/O模型,特别适用于需要处理大量并发连接的服务,如Web服务器或游戏服务器。相比于...
《C++版IOCP完成端口源码解析》 在计算机网络编程中,高性能服务器的构建是一项挑战,特别是在处理大量并发连接时。Windows操作系统提供了一种名为IOCP(I/O完成端口,Input/Output Completion Port)的技术,为...
IOCP(I/O Completion Port,I/O 完成端口)是 Windows 操作系统中用于高效处理并发 I/O 操作的一种机制。它被广泛应用于网络编程,尤其是服务器端的高并发场景,例如本示例中的“考试系统”。下面将详细阐述IOCP的...
【标题】"IOCp完成端口"是一种在Windows操作系统中用于高效处理I/O操作的技术,全称为"I/O Completion Ports"。这种技术主要应用于高并发、高性能的服务端应用程序,如网络服务器,数据库服务器等。它通过将I/O操作...
在这个"IOCP完成端口通讯例子"中,我们将探讨如何使用IOCP构建服务器端和客户端的通信。 1. **异步I/O原理**: 异步I/O模式允许程序在发起I/O操作后立即返回,继续执行其他任务,而无需等待I/O操作完成。当I/O操作...
IOCP(I/O Completion Port,I/O完成端口)是Windows操作系统中的一种高效I/O模型,主要用于处理大量的并发I/O操作。它通过将I/O操作的完成通知与一个或者多个线程池线程关联,实现了多线程环境下的高并发性能。在...
在本项目"C++语言实现的线程池,结合windowsIOCP完成端口,实现socket高并发服务端程序.zip"中,我们关注的核心是利用C++编程语言构建一个高性能的、支持高并发的TCP服务器。线程池和Windows的IO Completion Ports...
"IOCP完成端口"是一种用于提高Windows系统中网络服务性能的技术,它全称为"I/O完成端口"(Input/Output Completion Port)。本文将深入探讨IOCP的基本原理、优势以及如何在C++中使用它来构建高性能服务器。 IOCP是...
4. 创建IO完成端口,将socket绑定到IO完成端口上 5. 根据当前机器CPU个数创建工作者线程池 6. 使用AcceptEx()提前创建客户socket,创建个数与CPU个数相关 以上准备工作全部完成 7. 工作者线程池 ...
本文将深入探讨如何利用Visual C++和IOCP完成端口技术来构建一个网络数据传输的服务器和客户端。 1. IOCP基础: IOCP是Windows系统提供的一个机制,它允许多个线程共享一个I/O端口,处理来自多个I/O操作的完成通知...
通过学习和理解这个C++完成端口的例子,开发者可以深入掌握如何利用IOCP提高网络服务的性能和可扩展性,这对于构建大规模的服务器架构至关重要。同时,这个例子也适合初学者作为理解并发编程和网络编程的实践项目。
### IOCP完成端口之性能优化详解 在深入探讨IOCP(I/O Completion Port)的性能优化之前,我们首先简要回顾一下IOCP的基本概念及其在高性能网络编程中的作用。 IOCP是Windows操作系统提供的一种异步I/O模型,主要...
IOCP 完成端口原理 一、IOCP 简介 IOCP(I/O Completion Port)是一种异步I/O模型,用于提高服务器的吞吐量和可扩展性。在Windows平台上,IOCP是实现高性能服务器的首选技术。IOCP的基本架构图包括完成端口、等待...
在.NET编程环境中,C# IOCP(完成端口,I/O Completion Ports)是一种高级的并发I/O模型,常用于构建高性能的服务器应用。IOCP模型是Windows操作系统提供的一种高效的异步I/O机制,它能够充分利用多核处理器的优势,...
易语言IOCP完成端口源码,IOCP完成端口,Mem_Read_int,Mem_Write_int,子程序指针到整数,Call,GetAcceptExSockAddrs,AcceptEx,IntSocket,Socket_TCP,Socket_Bind,Socket_Listen,OverlappedCreate,OverlappedDestroy,...
**IOCP完成端口模型**,全称I/O完成端口(I/O Completion Port),是Windows API提供的一种高效处理大量并发I/O操作的机制。它主要用于优化多线程服务器应用程序,能够有效地支持高并发的网络服务,如HTTP服务器、...
socket UDP多播+用IOCP完成端口的例子源码.zip
IOCP(完成端口,Input/Output Completion Port)是Windows操作系统提供的一种高度优化的多线程I/O模型,尤其适用于处理大量并发连接的网络服务。在C#编程中,利用IOCP可以构建高效的TCP服务器,以应对大规模的并发...
IOCP(I/O Completion Port,I/O 完成端口)是Windows操作系统中的一种高度优化的I/O管理机制,主要用于处理大量并发的网络连接。它结合了重叠I/O模型,能够有效地提升服务器的性能,尤其在高并发场景下,如游戏...