一开始学习完成端口编程的时候,我看的资料是小猪的关于完成端口的教程和源代码。
好在,我还有那么一点点C++的底子,不是很好,勉强看得懂吧。
其实看得懂不是IOCP完成端口的具体原理,而是这些C++代码结构逻辑而已。
很惨,对吧。
后来我采用Delphi的代码结构来做,说真的,当时一样是一塌糊涂,哈哈。
很多人说,IOCP完成端口被神化了,其实这个很正常啊,不懂的时候,看啥都是神秘的。
其实小猪的这个代码很有用,他的执行测试Demo是我见到的最快的程序。
Delphi编码的程序,很多人的程序我测试过了,反应确实没有他快。客户端发送几百条数据,一边发,服务端一边不断地接收刷新数据,几乎没有延迟。感觉的确过瘾。
尤其是他的这个程序最难得的地方是把整个完成端口的流程合理简洁地制作出来。
而不像其它人,绕了几百个弯。
也许各人的理解不同,就有无数种结构。
但是能够做到简洁直接高效的,确实不多见。
所以我参考他的结构进行制作IOCP的内核。
测试的客户端软件,暂时使用下面这个:是C++代码制作的,不影响Delphi制作的服务端,呵呵。
100个连接,总共密集发送3次数据,效率还可以。这些只是很小的测试。
其实多线程比较容易发生内存冲突现象,当我测试的时候,有个相当奇特的现象引我注意,比如:
1 (***************************************************************************) 2 (* 初始化监听套接字 *) 3 (***************************************************************************) 4 function TComponentIocpSock.InitSOCKET(Const Addres:String;Const Port: Integer): Boolean; 5 begin 6 ------------------------------------------------------ 7 ------------------------------------------------------ 8 for I := 0 to FMAX_POST_ACCEPTEX - 1 do 9 begin 10 11 pAcceptIoContext:=GetNewIoContext;//PPerIoData(M_BusyIoDataList.Items[I]); 12 if not PostAccept(pAcceptIoContext) then 13 begin 14 MsgInfoEvent('PostAccept投递不成功!'); 15 RemoveContext(pAcceptIoContext); 16 Result :=False; 17 break; 18 end; 19 pAcceptIoContext:=nil; 20 end; 21 MsgInfoEvent('2:初始化套接字成功.'); 22 Result :=True; 23 end;
红色的地方是调用投递函数进行投递,然而四条线程分别执行完这块For循环之后,才轮到:
21 MsgInfoEvent('2:初始化套接字成功.');
22 Result :=True;
就是上面那里只执行一次,就等于是被分割出一块来大家一起抢着执行,而后面却只执行一次。
这种情况,到现在我才发现,真是想想很好笑。
后面再具体分析代码的编程。