DELPHI中完成端口(IOCP)的简单分析(1)

 
用DELPHI开发网络代码已经有一段时间了!
我发现在网上用VC来实现完成端口(IOCP)的代码很多,但是使用DELPHI来实现的就比较少了。对IOCP讲的清楚的就更少了。在这里我把自己编写DELPHI下的IOCP写出来,希望对刚学完成端口的朋友有个帮助。
首先我们来了解一些在使用IOCP的时候需要使用的一些结构!
(1):单IO数据结构
  LPVOID = Pointer;
  LPPER_IO_OPERATION_DATA = ^ PER_IO_OPERATION_DATA ;
  PER_IO_OPERATION_DATA = packed record
    Overlapped: OVERLAPPED;
    DataBuf: TWSABUF;
    Buffer: array [0..1024] of CHAR;
    BytesSEND: DWORD;
    BytesRECV: DWORD;
  end;
上面的结构中Overlapped: OVERLAPPED;和DataBuf: TWSABUF;是固定的结构类型。Buffer: array [0..1024] of CHAR;是用来保存接受数据的缓存。BytesSEND: DWORD;用来标志发送数据的长度。BytesRECV: DWORD;用来标志接受数据的长度。因为完成端口的工作者线程可以接受到来自客户端的数据,同时还可以接受到自己发送给客户端的数据,所以我们使用BytesSEND,BytesRECV变量来说是用来区分这次的数据是来自客户端的数据还是自己发送出去的数据。详细的使用方法,我会在下面详细说明。
(2):“单句柄数据结构”
  LPPER_HANDLE_DATA = ^ PER_HANDLE_DATA;
  PER_HANDLE_DATA = packed record
    Socket: TSocket;
  end;
下来我从编写一个完成端口的为例说明。
if WSAStartUp($202, wsData) <> 0 then
begin
   WSACleanup();
end;
加载SOCKET。我使用的是2.2版为了后面方便加入心跳。
CompletionPort:=CreateIOCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
创建一个完成端口。
GetSystemInfo(LocalSI);
for I:=0 to LocalSI.dwNumberOfProcessors * 2 -1 do
begin
   hThread := CreateThread(nil, 0, @ServerWorkerThread, Pointer(CompletionPort),0, ThreadID);
   if (hThread = 0) then
   begin
       Exit;
   end;
   CloseHandle(hThread);
end;
根据CPU的数量创建CPU*2数量的工作者线程。
Listensc:=WSASocket(AF_INET,SOCK_STREAM,0,Nil,0,WSA_FLAG_OVERLAPPED);
if Listensc=SOCKET_ERROR then
begin
    closesocket(Listensc);
    WSACleanup();
end;
sto.sin_family:=AF_INET;
sto.sin_port:=htons(5500);
sto.sin_addr.s_addr:=htonl(INADDR_ANY);
if bind(Listensc,sto,sizeof(sto))=SOCKET_ERROR then
begin
   closesocket(Listensc);
end;
listen(Listensc,20);
创建一个套接字,将此套接字和一个端口绑定并监听此端口。
while (TRUE) do
begin
   Acceptsc:= WSAAccept(Listensc, nil, nil, nil, 0);
   当客户端有连接请求的时候,WSAAccept函数会新创建一个套接字Acceptsc。这个套接字就是和客户端通信的时候使用的套接字。
   if (Acceptsc= SOCKET_ERROR) then
   begin
      closesocket(Listensc);
      exit;
   end;
   判断Acceptsc套接字创建是否成功,如果不成功则退出。
   PerHandleData := LPPER_HANDLE_DATA (GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA)));
   if (PerHandleData = nil) then
   begin
      exit;
   end;
   PerHandleData.Socket := Acceptsc;
   创建一个“单句柄数据结构”将Acceptsc套接字绑定。
   if (CreateIoCompletionPort(Acceptsc, CompletionPort, DWORD(PerHandleData), 0) = 0) then
   begin
      exit;
   end;
   将套接字、完成端口和“单句柄数据结构”三者绑定在一起。
   PerIoData := LPPER_IO_OPERATION_DATA(GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA)));
   if (PerIoData = nil) then
   begin
      exit;
   end;
   ZeroMemory(@PerIoData.Overlapped, sizeof(OVERLAPPED));
   PerIoData.BytesSEND := 0;
   PerIoData.BytesRECV := 0;
   PerIoData.DataBuf.len := 1024;
   PerIoData.DataBuf.buf := @PerIoData.Buffer;
   Flags := 0;
   创建一个“单IO数据结构”其中将PerIoData.BytesSEND 和PerIoData.BytesRECV 均设置成0。说明此“单IO数据结构”是用来接受的。
   if (WSARecv(Acceptsc, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
   begin
      if (WSAGetLastError() <> ERROR_IO_PENDING) then
      begin
         //最近在检查代码的时候发现以前这里只是使用Exit来退出是不正确的。这里需要删除申请的单IO数据结构,否子会出现内存泄露。 (2008年3月24日)
         //Exit;
        closesocket(AcceptSc);
        if PerIoData <> nil then
        begin
          GlobalFree(DWORD(PerIoData));
        end;
        Continue;
      end
   end;
   用此“单IO数据结构”来接受Acceptsc套接字的数据。
end;
创建IOCP的工作已经完成,下一次我将写IOCP的工作者线程的处理方法,谢谢!

DELPHI中完成端口(IOCP)的简单分析(1)的更多相关文章

  1. DELPHI中完成端口(IOCP)的简单分析(4)

    DELPHI中完成端口(IOCP)的简单分析(4)   在我以前写的文章中,一直说的是如何接收数据.但是对于如何发送数据却一点也没有提到.因为从代码量上来说接收的代码要比发送多很多.今天我就来写一下如 ...

  2. DELPHI中完成端口(IOCP)的简单分析(3)

    DELPHI中完成端口(IOCP)的简单分析(3)   fxh7622关注4人评论7366人阅读2007-01-17 11:18:24   最近太忙,所以没有机会来写IOCP的后续文章.今天好不容易有 ...

  3. DELPHI中完成端口(IOCP)的简单分析(2)

    DELPHI中完成端口(IOCP)的简单分析(2)   今天我写一下关于DELPHI编写完成端口(IOCP)的工作者线程中的东西.希望各位能提出批评意见.上次我写了关于常见IOCP的代码,对于IOCP ...

  4. java 中 “文件” 和 “流” 的简单分析

    java 中 FIle 和 流的简单分析 File类 简单File 常用方法 创建一个File 对象,检验文件是否存在,若不存在就创建,然后对File的类的这部分操作进行演示,如文件的名称.大小等 / ...

  5. rocketmq中的NettyRemotingClient类的简单分析

    rocketmq中的NettyRemotingClient类的简单分析 Bootstrap handler = this.bootstrap.group(this.eventLoopGroupWork ...

  6. Delphi中Android运行和JNI交互分析

    Androidapi.JNIBridge负责和JNI交互.,既然要交互,那么首先就是需要获得JNI的运行环境,Android本身内置的就有一个Java(Dalvik)虚拟机.所以这个第一步就肯定是要这 ...

  7. 关于Delphi中多线程传递参数的简单问题

    http://bbs.csdn.net/topics/390513469/ unit uThread; interface uses Classes; type Th = class(TThread) ...

  8. 不用注册热键方式在Delphi中实现定义快捷键(又简单又巧妙,但要当前窗体处在激活状态)

    第一步:在要实现快捷键的窗体中更改属性“KeyPreview”为True:第二步:在要实现快捷键的窗体中的OnKeyPress事件中填入一个过程名称(在Object Inspector中),填写好后回 ...

  9. jQuery中样式和属性模块简单分析

    1.行内样式操作 目标:扩展框架实现行内样式的增删改查 1.1 创建 css 方法 目标:实现单个样式或者多个样式的操作 1.1.1 css方法 -获取样式 注意:使用 style 属性只能获取行内样 ...

随机推荐

  1. mschart asp chart 用法,包括前台写法与后台写法,还有click事件,如何触发。

    纯后台动态生成aspchart ,这种方式没办法实现chart中click事件.click事件点击没有反应,用第二种可以实现点击事件. 两种方式实现同一种效果图: 第一种写法:后台动态生成aspcha ...

  2. FFmpeg: FFmepg中的sws_scale() 函数分析

    FFmpeg中的 sws_scale() 函数主要是用来做视频像素格式和分辨率的转换,其优势在于:可以在同一个函数里实现:1.图像色彩空间转换, 2:分辨率缩放,3:前后图像滤波处理.不足之处在于:效 ...

  3. 【Spark深入学习 -16】官网学习SparkSQL

    ----本节内容-------1.概览        1.1 Spark SQL        1.2 DatSets和DataFrame2.动手干活        2.1 契入点:SparkSess ...

  4. [转]decorators.xml的用法

    原文地址:https://blog.csdn.net/laozhuxiao/article/details/54342121 简介: sitemesh应用Decorator模式,用filter截取re ...

  5. C语言 · 数的划分

    算法训练 数的划分   时间限制:1.0s   内存限制:256.0MB        锦囊1 使用动态规划. 锦囊2 用F[i,j,k]表示将i划分成j份,最后一份为k的方案数,则F[i,j,k]= ...

  6. VM虚拟机下安装CentOS_6.5_x64

    在开始Linux的学习之前,我们必须要有一个实验环境.这里我选择了安装CentOS-6.5-x86_64的Minimal版本,大家也可以选择安装其他的Linux发行版.选择CentOS主要还是因为它比 ...

  7. css3 animation 在某些浏览器中特别快 bugfix

    今天在一款三星 4.2.2 的 webview 里,出现 animation 特别快的问题,把: .xxx{ -webkit-animation: xxx 24s linear infinite; } ...

  8. 【经验总结】- IDEA无法显示Project目录怎么办

    1. 关闭IDEA 2.然后删除项目文件夹下的.idea文件夹 3.重新用IDEA工具打开项目 4.再次点击如下图即可搞定    

  9. there was an error running the selected code generator unable to retrieve metadata for

    there was an error running the selected code generator unable to retrieve metadata for PROBLEM: I ha ...

  10. JS 一张图理解prototype、proto和constructor的关系

    转载于原文地址:https://www.cnblogs.com/xiaohuochai/p/5721552.html(感谢大神的总结) 前面的话 javascript里的关系又多又乱.作用域链是一种单 ...