IOCP踩坑

IOCP函数

创建IOCP句柄和关联套接字到IOCP句柄,都是通过CreateIoCompletionPort
创建IOCP句柄

HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

关联套接字到IOCP句柄

CreateIoCompletionPort((HANDLE)fd, iocp, 0, 0);

获取完成事件

GetQueuedCompletionStatus(iocp, &bytes, &key, &povlp, timeout);

返回值为FALSE,表示有错误发生,可通过WSAGetLastError获取错误码,超时错误码为WAIT_TIMEOUT
ConnectEx连接失败,会返回对应错误码
WSASend/WSARecv失败,bytes=0

ConnectEx返回10022

调用ConnectEx前需要先调用bind,绑定到一个指定端口,或者可以绑定到0让系统自动分配端口

getpeername无法获取到对端地址

对应AcceptEx接收的connfd,getpeername前需要调用

setsockopt(connfd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (const char*)&listenfd, sizeof(int));

对应ConnectEx连接的connfd,getpeername前需要调用

setsockopt(connfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);

other

AcceptEx, GetAcceptExSockaddrsConnectEx, DisconnectEx需要通过WSAIoctl获取函数指针

AcceptExConnectExWSARecvWSASend这些重叠IO函数和IOCP的完整使用示例参考
https://github.com/ithewei/hw/blob/master/event/overlapio.c
https://github.com/ithewei/hw/blob/master/event/iocp.c

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
国人开发强悍IOCP代码,全部代码 其中一个单元的代码: unit uIOCompletionPort; interface uses Windows, WinSock2, uWin32Const, uException, uDIProtocol, uDIClientChannel; type TIOCompletionPort = class private m_hCompletionPort: Thandle; private procedure CreateCompletionPort; public function AssociateSocketWithCompletionPort( hDevice: THandle; dwCompletionKey: DWORD): Boolean; function GetIOCompletionStatus( var FClientChannel: TDIClientChannel; var pHandleData: PPerHandleData; var dwIoSize: DWORD): Boolean; overload; function GetIOCompletionStatus( var FClientChannel: TDIClientChannel; var pHandleData: PPerHandleData; var dwIoSize: DWORD; dwMilliseconds: DWORD): Boolean; overload; function PostIOCompletionStatus( lpCompletionKey: DWORD; lpOverlapped: POverlapped; lpNumberOfBytesTransferred: DWORD): Boolean; public constructor Create; destructor Destroy; override; end; implementation constructor TIOCompletionPort.Create; begin inherited Create; CreateCompletionPort; end; destructor TIOCompletionPort.Destroy; begin CloseHandle(m_hCompletionPort); inherited Destroy; end; procedure TIOCompletionPort.CreateCompletionPort; var s: TSocket; begin s := Winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (s = Winsock2.INVALID_SOCKET) then raise TException.Create(ErrWin32Error, GetLastError(), 'Winsock2.socket'); m_hCompletionPort := CreateIOCompletionPort(s, 0, 0, 0); if (m_hCompletionPort = 0) then raise TException.Create(ErrWin32Error, GetLastError(), 'CreateIOCompletionPort'); Winsock2.closesocket(s); end; function TIOCompletionPort.AssociateSocketWithCompletionPort( hDevice: THandle; dwCompletionKey: DWORD ): Boolean; var h: THandle; begin Result := TRUE; h := CreateIOCompletionPort(hDevice, m_hCompletionPort, dwCompletionKey, 0); if (h m_hCompletionPort) then begin Result := FALSE; raise TException.Create(ErrWin32Error, GetLastError(), 'AssociateSocketWithCompletionPort'); end; end; function TIOCompletionPort.GetIOCompletionStatus( var FClientChannel: TDIClientChannel; var pHandleData: PPerHandleData; var dwIoSize: DWORD): Boolean; begin Result := GetQueuedCompletionStatus( m_hCompletionPort, dwIOSize, DWORD(FClientChannel), POVERLAPPED(pHandleData), INFINITE ); end; function TIOCompletionPort.GetIOCompletionStatus( var FClientChannel: TDIClientChannel; var pHandleData: PPerHandleData; var dwIoSize: DWORD; dwMilliseconds: DWORD): Boolean; var bRet: Boolean; nLastError: DWORD; begin bRet := TRUE; if FALSE = GetQueuedCompletionStatus( m_hCompletionPort, dwIOSize, DWORD(FClientChannel), POVERLAPPED(pHandleData), INFINITE ) then begin nLastError := GetLastError(); if (nLastError WAIT_TIMEOUT) then raise TException.Create(ErrWin32Error, GetLastError(), 'GetQueuedCompletionStatus'); bRet := FALSE; end; Result := bRet; end; function TIOCompletionPort.PostIOCompletionStatus( lpCompletionKey: DWORD; lpOverlapped: POverlapped; lpNumberOfBytesTransferred: DWORD): Boolean; begin Result := PostQueuedCompletionStatus( m_hCompletionPort, lpNumberOfBytesTransferred, lpCompletionKey, lpOverlapped ); end; end.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithewei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值