FD_READ,FD_WRITE等网络事件在什么情况下被触发呀?

vagabondkq 2003-09-14 09:58:52
好像不是有数据可读或可写触发的呀?
那到底是什么触发的这些网络事件呢?
...全文
520 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
lostgdi731 2003-12-08
  • 打赏
  • 举报
回复
to zhanshenpkl(LittlePK)
in your answer :"我经过测试,如果我在OnReceive()函数的最后调用AsyncSelect(FD_WRITE),而在OnSend()函数的最后调用AsyncSelect(FD_READ),那么就会不断的循环。"
应该是OnReceive()后调用AsyncSelect(FD_READ)吧?
zhanshenpkl 2003-09-16
  • 打赏
  • 举报
回复
To vagabondkq(birder):
我把MSDN里关于WSAAsyncSelect()函数的一段英文摘出来大家看看:
The WS2_32.DLL will not continually flood an application with messages for a particular network event. Having successfully posted notification of a particular event to an application window, no further message(s) for that network event will be posted to the application window until the application makes the function call that implicitly reenables notification of that network event.

如果你想再发送数据就再次调用Select语句,那么当系统准备好(我的理解是它的缓冲区的数据已经全部发送出去了,可以再接受新的数据)就会再次触发FD_WRITE事件。
再看下面一段英文:
An FD_WRITE message is posted when a socket is first connected with connect or WSAConnect (after FD_CONNECT, if also registered) or accepted with accept or WSAAccept, and then after a send operation fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will be notified that sends are again possible with an FD_WRITE message.
在连接成功后,就会触发一个FD_WRITE事件。
综合这两句话,如果你不再次调用Select的话,那么它只会触发在连接之后那次FD_WRITE。

我经过测试,如果我在OnReceive()函数的最后调用AsyncSelect(FD_WRITE),而在OnSend()函数的最后调用AsyncSelect(FD_READ),那么就会不断的循环。

以上只是个人的理解,仅供参考,不对的话还请各位大哥指教
lostgdi731 2003-09-16
  • 打赏
  • 举报
回复
Up
xiaohyy 2003-09-15
  • 打赏
  • 举报
回复
触发网络事件是由系统控制的吧。。
thisisyjs 2003-09-15
  • 打赏
  • 举报
回复
简单说一点: 当你调用 send 或者 sendto 时就会有 FD_WRITE 事件。
vagabondkq 2003-09-15
  • 打赏
  • 举报
回复
还有,触发网络事件是由程序控制的还是由系统控制的呢?或者是都可以控制?
vagabondkq 2003-09-15
  • 打赏
  • 举报
回复
谢谢各位关心,但只有dahai_2002(大海)回答的是正题。
但我还是搞不懂。
比如说FD_WRITE,在WSAAsyncSelect和WSAEventSelect模型中都是如果有FD_WRITE这个网络事件触发,然后send()数据的。但dahai_2002(大海)说的是,如果有数据可以发出(这不应该是我们在程序里控制的吗?比如send()),再产生FD_WRITE事件。这显然是矛盾的呀?!
我理解的程序流程是这样的,点击发送按钮或敲命令行,触发网络事件FD_WRITE,然后通过WSAAsyncSelect模型的控制发送数据出去。现在问题是“点击发送按钮或敲命令行,怎么触发的网络事件FD_WRITE?”
其他的事件呢?FD_CLOSE,FD_CONNECT等。
dahai_2002 2003-09-15
  • 打赏
  • 举报
回复
FD_READ网络事件在出现下列情况之一就被触发:
1、输入缓冲区有数据可以读入;
2、连接已经关闭,重设或中止;
3、若已调用了listen,而且accept函数成功接收一个连接。
FD_WRITE网络事件在出现下列情况之一就被触发:
1、有数据可以发出;
2、如果已完成了对一个非锁定连接调用的处理连接就会成功。
HanZhu1 2003-09-15
  • 打赏
  • 举报
回复
先要注册这些事件,当相应的事件产生时就会停止休眠
zsc0797 2003-09-15
  • 打赏
  • 举报
回复
先使用WSAAsyncSelect()函数,
int WSAAsyncSelect(
SOCKET s, //你上头建立的套接字
HWND hWnd, //获取消息的窗口句柄
unsigned int wMsg,//自定义的用户消息
long lEvent //你想获取的事件组合
);

如:
#define WM_SOCK WM_USER+1

WSAAsyncSelect(s, hwnd, WM_SOCK, FD_READ | FD_WRITE);
这样当产生相应事件时将触发WM_SOCK消息,你可以在窗口过程中捕获该消息。
并利用WSAGETSELECTEVENT宏来取得到底是什么事件,具体去查MSDN吧

我这有些例子,你要的话,也可以发给你。
vagabondkq 2003-09-15
  • 打赏
  • 举报
回复
我看了,没看明白,其实好像是书里就没讲,希望有人指点一下。
AaronChan 2003-09-15
  • 打赏
  • 举报
回复
建议看下《WINDOWS网络编程》
xhwu3721 2003-09-15
  • 打赏
  • 举报
回复
gz
vagabondkq 2003-09-15
  • 打赏
  • 举报
回复
up
phoenixandlinda 2003-09-15
  • 打赏
  • 举报
回复
WSAAsyncSelect和WSAEventSelect只是向系统注册用户关心事件,并不会打乱流程,只需要安心的等待“东窗事发”。

类似下面的响应:
switch(nEvent)
{

case FD_ACCEPT: 表示现在已经有连接被listen到了,可以执行Accept操作了
……
case FD_READ: 表示现在已经有数据在缓冲区了,可以执行recv操作了
……
case FD_WRITE: 表示现在缓冲区已经空闲了,可以执行send操作了
……
case FD_CLOSE: 表示现在有连接断开了
……
}
lovemaggic 2003-09-15
  • 打赏
  • 举报
回复
系统运行到代码Send时,会产生事件并发送消息,对用户来说,是透明的,用户只是知道Cilck Button,消息循环会自动检测消息并执行事件.呵呵
vagabondkq 2003-09-15
  • 打赏
  • 举报
回复
zhanshenpkl(LittlePK):
按你所说,这些事件都是由系统产生,我们不需要控制它们了?
那比如说我需要send()数据,怎么样才能主动获取FD_WRITE事件那?你所说的“系统准备好了可以发送数据”,所谓“系统准备好”是指什么呢?
希望不吝赐教:)
leon7909 2003-09-15
  • 打赏
  • 举报
回复
我也有点搞不懂这个FD_WRITE,都说是在系统准备好了可以发送数据了而产生的事件,可是这就怪了,不管我这是客户端还是SERVER端,只要建 立了正确的连接,应该说这时候就已经准备好了可以发送数据了吧,那我调 SEND,该发的发出去了,可是这时应该说连接还是准备好可以发送数据的状态吧,这时我没有要发的数据啊,调用SELECT的时候难道就不停的LOOP吗?如果不是我说的这样,而是阻在SELECT那个地方的话,那我这时又有了要发的数据了呢?我怎么才能让FD_WRITE事件产生呢?
zhanshenpkl 2003-09-15
  • 打赏
  • 举报
回复
FD_CONNECT:指当你调用connect函数后,函数执行后如果你是采用非阻塞的,那么当你所尝试的连接完成后,系统产生该事件通知你本次调用的结果(成功还是失败以及失败的原因),你可以看MSDN的CAsyncSocket类中OnConnect的说明;
FD_CLOSE:一般可以分为几种:本地关闭,远端主机关闭连接和系统检测到网络线路问题。这两者关闭连接都会系统都会产生该事件通知你套接字被关闭;
其它如FD_ACCEPTE、FD_OOB都大同小异,就是有什么东东到了系统产生相应的事件通知你去处理
如果你调用AsyncSelect()函数,那么该函数的参数就是你只允许系统通知你这个事件,其它事件不需要
zhanshenpkl 2003-09-15
  • 打赏
  • 举报
回复
FD_WRITE是指系统准备好了可以发送数据了而产生的事件,我们通常都是在这个事件的响应函数中调用发送数据函数Send()的;
FD_READ也是一样,指系统已收到数据并存储在系统的缓冲区了而产生的事件,我们就在响应该事件的响应函数中调用Recv()把系统缓冲区中的数据读取到自己的缓冲区里。

18,356

社区成员

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

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