用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的工作者线程的处理方法,谢谢!

转载于:https://www.cnblogs.com/fxh7622/archive/2010/04/11/1709848.html

DELPHI中完成端口(IOCP)的简单分析(1)相关推荐

  1. 直立车模控制中三种滤波算法简单分析(清华卓晴)

    摘自:https://mp.weixin.qq.com/s/WbCh0NFAnsf9y2blQenf7g 让我想起余义的一篇文章也是说到平衡车有三种滤波,我想和卓晴说的是一样的吧. https://b ...

  2. python中“羊车门问题”的简单分析与代码实现

    1."羊车门问题"题目及要求. 2.问题的数学逻辑分析. 3.python代码分析出换和不换的概率. "羊车门问题"题目及要求: 有三扇关着的门,一扇门后面停着 ...

  3. linux中524端口,liunx下攻击分析及如何通过交换机封端口

    4上汇聚层交换机封IP段 进入华为交换机: [Huawei]int xg0/0/4 //进入对应的接口 [Huawei-GigabitEthernet0/0/4]un traffic-filter i ...

  4. oracle中会话和连接数的简单分析

    通俗来讲,会话(Session) 是通信双方从开始通信到通信结束期间的一个上下文(Context).这个上下文是一段位于服务器端的内存:记录了本次连接的客户端机器.通过哪个应用程序.哪个用户登录等信息 ...

  5. Java中final关键字作用的简单分析

    final关键字可以用来修饰引用.方法和类. 一.用来修饰一个引用 如果引用为基本数据类型,则该引用为常量,该值无法修改: 如果引用为引用数据类型,如对象.数组,则该对象.数组本身可以修改,但指向该对 ...

  6. php strlen ctf,CTF中的PHP反序列化漏洞简单分析

    [PHP] 纯文本查看 复制代码<?php class start_gg { public $mod1; public $mod2; public function __construct()  ...

  7. delphi中pos函数怎么用?

    pos(a,b)函数用法如下:取出子串a,在父串b中第一次出现的位置. 例如: pos('b','abcd'): 返回结果是2: 在delphi中使用汇编异常的简单,只用使用关键字asm ....en ...

  8. 蛙蛙推荐:在c#使用IOCP(完成端口)的简单示例

    蛙蛙推荐:在c#使用IOCP(完成端口)的简单示例 上次给大家发了利用winsock原生的api来做一个同步的socket服务器的例子,大致上只是贴了一些代码,相信大家这么冰雪聪明,已经研究的差不多了 ...

  9. 802.1Q中的secure/check/fallback/disable的简单分析

    802.1Q中的secure/check/fallback/disable的简单分析 芯片手册原文 Security & Port Mapping The 802.1Q Security fe ...

  10. 在c#使用IOCP(完成端口)的简单示例

    上次给大家发了利用winsock原生的api来做一个同步的socket服务器的例子,大致上只是贴了一些代码,相信大家这么冰雪聪明,已经研究的差不多了.因为winsock的api使用在msdn或者goo ...

最新文章

  1. 最短路算法总结(入门版)
  2. Linux Kernel TCP/IP Stack — 协议栈收包处理流程
  3. PHP学习资源收集~
  4. spring问题--Unable to validate using XSD
  5. ob_start()失效与phpunit的非正常结束
  6. Android之jni调用java函数总结
  7. 如何用C++来计算大数字乘法
  8. My97DatePicker日期控件的使用
  9. 同源策略——浏览器安全卫士
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的高校勤工助学管理系统
  11. docker mysql node_Docker打包nodejs项目和数据库
  12. 谷粒商城:14.全文检索ElasticSearch
  13. double im2double mat2gray之一二说
  14. 【语音处理】基于matlab语音去噪频谱分析【含Matlab源码 1019期】
  15. 面试题单例模式的五种写法(枚举妙用)
  16. GRLDR外部MENU.LST调用GRLDR内部菜单
  17. 无人机油动发动机调试
  18. 接入翼支付的php,翼支付商户接入规范.doc
  19. matlab里添加白噪声,转Matlab中添加高斯白噪声
  20. 阿卡迪亚大学计算机专业好考吗,申请阿卡迪亚大学究竟难不难?

热门文章

  1. Linux学习记录--命令与文件的查询
  2. Android第一个程序Say Hello To Android
  3. mysql的瓶颈_MySQL 瓶颈分析及优化
  4. 华为鸿蒙 os 适配机型曝光,华为鸿蒙OS 2.0首批适配机型曝光
  5. docker portainer_Docker可视化管理:Portainer中文版
  6. azure java_使用 Java 的 Azure 存储示例 | Microsoft Docs
  7. 生成springboot banner网站
  8. 中职计算机多媒体教材,中职汽车维修课中计算机多媒体教学的实施
  9. 7. 锁定框架(The Locking Framework)
  10. Spring源码之bean的加载(五)准备创建bean