采用完成例程的重叠IO模型问题

ppyy 2003-11-20 07:24:25
我在重叠IO模型里的完成例程里,能同时投递一个WSARecv和WSASend请求吗?我的推测是可以的,因为这两个函数都是异步函数。。但是如果同时投递了这两个请求,当其中一个请求完成后,WSAWaitForMultipleEvents返回,我如何才能判断出是WSARecv完成了还是WSASend完成了?
...全文
213 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevencat 2003-11-22
  • 打赏
  • 举报
回复
overlapped就是放自己数据的地方。一般是放缓冲区的。
用来表示per operation的东西的。

还有一个cp key是用来放socket类的指针的。用来找到套接字类用的。

这两个数据应该是理解的关键了。我想。
ppyy 2003-11-21
  • 打赏
  • 举报
回复
flagfly(我也不知道要去哪里) :
谢谢你。我明白了。

huangbeyond(校园人渣) :

另外,昨天我又考虑了一下,发现在使用完成例程的重叠IO里,EVENT并不需要像采用事件处理那样和OVERLAPPED相关联,WSAWaitForMultipleEvents的返回值是无法区分出是哪一个套接字的IO完成了。。。
flagfly 2003-11-21
  • 打赏
  • 举报
回复
这种转换是可以的。因为SOCKET_INFORMATION结构的第一个成员是OVERLAPPED,转换后,其第一个成员的值正确,其他成员的值不定,根据内存中Overlapped后的内容确定。
photoman 2003-11-21
  • 打赏
  • 举报
回复
单句柄数据怎么进去怎么出来,这个就是判断条件哈,需要什么自己定就是了
everandforever 2003-11-21
  • 打赏
  • 举报
回复
书读百遍, 其义自现. WINDOWS 网络编程完成端口那一章看他个100遍包你懂.
ppyy 2003-11-21
  • 打赏
  • 举报
回复
我觉得采用完成例程的重叠IO模型真的很难理解,,,
虽然大体的原理我明白了
ppyy 2003-11-21
  • 打赏
  • 举报
回复
还是不太明白,,,,
这是WINDOWS网络编程光盘里的代码:

他在完成例程里有如下的代码
LPSOCKET_INFORMATION SI = (LPSOCKET_INFORMATION) Overlapped;

if (Error != 0)
{
printf("I/O operation failed with error %d\n", Error);
}

if (BytesTransferred == 0)
{
printf("Closing socket %d\n", SI->Socket);
}

if (Error != 0 || BytesTransferred == 0)
{
closesocket(SI->Socket);
GlobalFree(SI);
return;
}


我不理解的是SI->Socket是怎么来的,,,
SI结构如下:
typedef struct _SOCKET_INFORMATION
{
OVERLAPPED Overlapped;
SOCKET Socket;
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
DWORD BytesSEND;
DWORD BytesRECV;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;


为什么对OVERLAPPED强制转换后就可以直接引用 SOCKET_INFORMATION结构的Socket成员
这个socket成员是如何传递过来的?
raphyer 2003-11-21
  • 打赏
  • 举报
回复
slimak原作:
http://www.csdn.net/Develop/Read_Article.asp?Id=22078
ppyy 2003-11-20
  • 打赏
  • 举报
回复
sevencat(七猫):

在完成例程里,OVERLAPPED到底表示一个什么东西。,,,为什么我在《WINDOWS网络编程技术》里看代码发现代码里定义了一个结构:
typedef struct _SOCKET_INFORMATION
{
OVERLAPPED Overlapped;
SOCKET Socket;
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
DWORD BytesSEND;
DWORD BytesRECV;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;

然后他在完成例程里
void CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred,
LPWSAOVERLAPPED Overlapped, DWORD InFlags)
{
DWORD SendBytes, RecvBytes;
DWORD Flags;

// Reference the WSAOVERLAPPED structure as a SOCKET_INFORMATION structure
LPSOCKET_INFORMATION SI = (LPSOCKET_INFORMATION) Overlapped;

这样也进行了强制转换,这样的强制转换到底有什么用,是什么意思?
然后他就把转换后的Overlapped作为SOCKET_INFORMATION 结构来使用了,
我不明白,请指点
ppyy 2003-11-20
  • 打赏
  • 举报
回复
huangbeyond(校园人渣):

你所指的状态保存是什么意思?
另外,你说“WSAWaitForMultipleEvents的返回值,已经包含了该EVENT的INDEX,拿它和你进行WSAXxxx操作时使用的EVENT进行比较,就可以确定是哪一个完成了.”

比如我现在在同一个套接字上同时投递了WSARecv和WSASend两个请求,
WSAWaitForMultipleEvents返回了,我根据返回的INDEX得到了那个套接字,但是还是一样的无法分析是WSASend完成了还是WSARecv 完成了。

另外我还有点不清楚,WSAWaitForMultipleEvents在某一个异步请求完成后,返回的是WAIT_IO_COMPLETION,但是怎么又能同时表示出EventArray里的INDEX呢?
百思不得其解
sevencat 2003-11-20
  • 打赏
  • 举报
回复
重叠IO我没用过.
完成端口里面我是把包的操作写在OVERLAPPED里面
CBuffer :public OVERLAPPED
{

int m_type;(假如是读的话先设为READ_COMPLETED,假如是写的话设为WRITE_COMPLETED)
}
然后在收到后将OVERLAPPED强制转换为CBUFFER.
取出操作后做相应处理写的就删掉,读的就处理.
huangbeyond 2003-11-20
  • 打赏
  • 举报
回复
如果你的IO模型里,不需要状态保存,那么,可以同时投递多个WSARecv和WSASend请求;
如果是需要状态保存的,最好使用"串口模式",即一次只实现一个异步WSAXxxx操作.

WSAWaitForMultipleEvents的返回值,已经包含了该EVENT的INDEX,拿它和你进行WSAXxxx操作时使用的EVENT进行比较,就可以确定是哪一个完成了.

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧