关于Overlapped模式的问题(300分)

  • 主题发起人 主题发起人 ego
  • 开始时间 开始时间
E

ego

Unregistered / Unconfirmed
GUEST, unregistred user!
我把《Windows网络编程》上第五章的“重叠模式”例子改写为Delphi,虽然运行成功,但在扩展这个例子的时候却不知怎样去管理多个套接字。
我现在的办法比较笨:每一次accept后就建立一个线程用来WSARecv,呵呵,效率太低了,还不如WSAEventSelect模式。

还有一个问题:WSAEventSelect模式中,可以用WSAEnumNetWorkEvents来枚举WSAWaitForMultipleEvents发生的事件类型,
而在Overlapped模式中,每次WSAWaitForMultipleEvents之后,接着用WSAGetOverlappedResult来分析结果,但是WSAGetOverlappedResult
只能得到WSARecv的内容,其它Send和Close事件应该怎样处理呢?

总之看Overlapped模式的时候总有些糊里糊涂,希望哪位高人给个示例源码来参考参考。谢谢!
 
没人回答?是不是我说得太不清楚了?
 
>>在Overlapped模式中,每次WSAWaitForMultipleEvents之后,接着用
>>WSAGetOverlappedResult来分析结果

我不喜欢上述模式,因为WSAWaitForMultipleEvents和WaitForMultipleEvents一样最多只能同时等待64个Event,还不如开64个线程用阻塞模式代码来的简单(线程阻塞模式最多能同时处理1008个左右的连接--也就是最多能同时开1008个线程)。
建议使用WSAxxxx(WSARecv, WSARecvFrom, WSASend, WSASendTo)这些api中的CompletionRoutine(也就是回调函数,overlapped中的一种)模式来做,在CompletionRoutine中可以用WSAGetOverlappedResult来获知具体是哪个socket的overlapped结构
当然更好的办法是用完成端口来处理WSARecv, WSARecvFrom, WSASend, WSASendTo这些api的overlapped结果。用完成端口的另一个好处是可以用AcceptEx来接受远端连接,效率更高。
 
to Another_eYes:
谢谢您的回答。
您说的CompletionRoutine我现在正在看,暂时还没结果。但我现在很想知道重叠模型中,用事件通知的方式来完成的细节。不过,看样子我要暂时跳过这一种模式了。
 
欢迎大家发言,此贴长期有效 ^_^
 
WSAGetOverlappedResult我现在写的时候省略掉了
以前也用,但发现CPU占用率很高,后来发现去掉他后CPU占用率降了很多

而且手法数据也很正常,觉得和加上没有什么区别:)具体我也不知道为什么

其实我对这个模型也有点糊涂的,我也来听课
 
不会吧,去掉WSAGetOverlappedResult以后怎么判断重叠请求的状态呢?比如通信方已经关闭了。
 
不好意思,我刚才又看了一下,去的好像不是WSAGetOverlappedResult
可我既不的是哪个了,好像是和OVERLAPPED有关的一个,时间久了
既不的了了,呵呵
 
其实重叠I/O很好用,速度也还不错。不是什么时候都要用完成端口得。
 
是呀,windows98不支持完成端口,所以有时重叠I/O还是很有用的。
诸位大侠能不能详细点,三言两语偶还是不明白。
 
你们看TServerSocket和TClientSocket的代码,他们里面也用了重叠I/O哦,
 
function TWinSocketStream.Read(var Buffer; Count: Longint): Longint;
var
Overlapped: TOverlapped;
ErrorCode: Integer;
begin
FSocket.Lock;
try
FillChar(OVerlapped, SizeOf(Overlapped), 0);
Overlapped.hEvent := FEvent.Handle;
if not ReadFile(FSocket.SocketHandle, Buffer, Count, DWORD(Result),
@Overlapped) and (GetLastError <> ERROR_IO_PENDING) then
begin
ErrorCode := GetLastError;
raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketRead, ErrorCode,
SysErrorMessage(ErrorCode)]);
end;
if FEvent.WaitFor(FTimeOut) <> wrSignaled then
Result := 0
else
begin
GetOverlappedResult(FSocket.SocketHandle, Overlapped, DWORD(Result), False);
FEvent.ResetEvent;
end;
finally
FSocket.Unlock;
end;
end;
 
看看先。不过ScktComp.pas用的是Winsock1,好多Winsock2的东东都不支持。
 
WriteFile和ReadFile可以把SOCKET当文件读写,所以间接通过这个支持重叠I/O
 
呵呵,原来自己对WSAGetOverlappedResult的理解错误,其实WSAGetOverlappedResult返回的是对应的套接字。Overlapped模式的例子扩展总算测试通过了。
谢谢大家了!
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部