[转帖]IOCP配合AcceptEx的例子(2)


 

这是在学《Windows网络编程(第二版)》第六章时制作的一个例子由于书中没有给出简洁的例子,本人在学这里时就费了很多时间。
现在把完成的代码贴出来,供大家参考。
本程序在VS2003编译器编译运行。在6.0下可能需要稍加修改。

DWORD WINAPI ServerThread(LPVOID lpParam)
{
HANDLE CompletionPort = (HANDLE)lpParam;
DWORD bytes;
LPPER_HANDLE_DATA perHandleData = NULL; //单句柄数据
LPPER_IO_DATA perIoData; //单IO数据
DWORD Flags;
int ret;
DWORD RecvBytes;
//进入循环的等待重叠操作的完成
while(true)
{
bytes = -1;
ret=GetQueuedCompletionStatus(
CompletionPort, //原先的完成端口句柄
&bytes, //重叠操作完成的字节数
(LPDWORD)&perHandleData, //原先和完成端口句柄关联起来的单句柄数据
(LPOVERLAPPED*)&perIoData, //用于接收已完成的IO操作的重叠结构
INFINITE); //在完成端口上等待的时间 INFINITE 为无限等待

//先检查在套接字上是否发生错误
//当发生错误时关闭套接字同时释放掉所有的内存.
int i = 0;
if(bytes == 0 && (perIoData->operatorType == RECV ||
perIoData->operatorType == SEND))
{
closesocket(perHandleData->socket);
GlobalFree(perHandleData);
GlobalFree(perIoData);
cout<<"closesocket and globalfree perhandledata periodata!"<<endl;
continue;
}
//这是AcceptEx函数处理完成,在下面处理
if(perIoData->operatorType == ACCEPT) //处理连接操作
{
//使用GetAcceptExSockaddrs函数 获得具体的各个地址参数.
if(setsockopt( perIoData->client, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, 
( char* )&(perHandleData->socket ), sizeof( perHandleData->socket ) )==SOCKET_ERROR)
cout<<"setsockopt..."<<endl;

perHandleData->socket = perIoData->client;

//memcpy(&(perHandleData->clientAddr),raddr,sizeof(raddr));
//将新的客户套接字与完成端口连接
CreateIoCompletionPort((HANDLE)perHandleData->socket,
CompletionPort,(ULONG_PTR)perHandleData,0);

memset(&(perIoData->overlapped),0,sizeof(OVERLAPPED));
perIoData->operatorType = RECV; //将状态设置成接收
//设置WSABUF结构
perIoData->buffer.buf = perIoData->dataBuffer;
perIoData->buffer.len = perIoData->dataLength = DATA_LENGTH;

cout<<"wait for data arrive(Accept)..."<<endl;
Flags = 0;
if(WSARecv(perHandleData->socket,&(perIoData->buffer),1,
&RecvBytes,&Flags,&(perIoData->overlapped),NULL)==SOCKET_ERROR)
if(WSAGetLastError()==WSA_IO_PENDING)
cout<<"WSARecv Pending..."<<endl;
continue; 
}
if(perIoData->operatorType == RECV)
cout<<perIoData->buffer.buf<<endl; //将接收到的数据显示出来
Flags = 0;
perIoData->operatorType = RECV; //设置成接受数据类型

ZeroMemory(&(perIoData->overlapped),sizeof(OVERLAPPED));
//重新投递一个新的接收请求
cout<<" wait for data arrive..."<<endl;
WSARecv(perHandleData->socket,&(perIoData->buffer),1,
&RecvBytes,&Flags,&(perIoData->overlapped),NULL);
}

return 0;
}
在前面有贴出了一个简单的客户端例子,可以结合起来调试,很方便的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值