织梦CMS - 轻松建站从此开始!

罗索

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

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

这是在学《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;
}
在前面有贴出了一个简单的客户端例子,可以结合起来调试,很方便的。
欢迎同道同志来信讨论 chang841018@yahoo.com.cn

(iwgh)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/200703/6626.html]
本文出处:网络博客 作者:iwgh
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容