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

vagabondkq 2003-09-14 09:58:52
好像不是有数据可读或可写触发的呀?
那到底是什么触发的这些网络事件呢?
...全文
516 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()把系统缓冲区中的数据读取到自己的缓冲区里。
Re:CCNA_CCNP 思科网络认证 动态路由 EIGRP 和 OSPF 协议======================# EIGRP协议特点(CISCO产品专用独家协议) 使用Hello消息发现邻居,然后交换路由信息,使用Hello包维持邻居表 代替其它动态协议周期性更新而消耗资源。 有备用路径,当最佳路径不可用,立即使用备用路径 备用路径比动态获取新路径效率更高。 度量值默认为带宽和延迟,也可以添加负载和可靠性以及最大传输单元(MTU) rip只是hops跳数为依据,使用带宽和延时为指标更合理 还可以负载、可靠性和MTU为依据,选择最佳路径。 默认支持4条链路的不同代价的负载均衡,可以更改为最多6条 最大跳数为255(默认是100跳) rip只有15hops,所有只能够使用在小型网络中。 触发式更新路由表,即网络发生变化时,增量更新 hello包和触发式结合,消耗设置资源更低 支持路由的自动汇总。 支持大的网络,可以使用自制系统号来区别可共享路由信息的路由器集合,路由信息只可以在拥有相同自制系统号的路由器间共享。 (即一片路由和另一片路由,不计划发布沟通的情况下,可以以系统号区分) 如同VLAN方式 管理距离是90 直连0静态路由1;rip协议120;EIGRP协议90(比rip优先级高) # EIGRP度量值 EIGRP度量值 带宽 延迟 可靠性 负载 最大路径和跳数 默认支持4条等价路径 最大跳数100,也可以设置成255 # EIGRP三张表 邻居关系表 拓扑表 路由表 # EIGRP专业术语 可行距离(FD)                :A到E最小开销的路径(最佳路径) 被通告距离(AD)            :A的前一个路由器,到E的开销 继任者(最佳路径)          :可行路径下一跳的路由器 可行的继任者(备用路径):被通告距离 ---------------------------------------------------------------------------------------# 介绍OSPF协议 开放最短路径优先(OSPF)是一个开放标准的路由选择协议,它被各种网络开发商所广泛使用。 即无厂家边界 # OSPF协议具有下列特性: 由区域和自治系统组成 最小化的路由更新的流量(触发式更新,平时hello包打招呼,类eigrp协议) 允许可缩放性 支持变VLSM和CIDR(五类间路由/23) 拥有不受限的跳数 允许多销售商的设备集成(开放的标准) 度量值是带宽 # OSPF术语 Router-ID(网络中的身份:取ip最大值) 网络中运行OSPF协议的路由器都要有一个唯一的标识,这就是Router-ID,并且Router-ID在网络中绝对不可以有重复。 COST(开销) OSPF协议选择最佳路径的标准是带宽,带宽越高计算出来的开销越低。到达目标网络的各个链路累计开销最低的,就是最佳路径。 链路(Link) 就是路由器上的接口,在这里,应该指运行在OSPF进程下的接口。 链路状态(Link-State) 链路状态(LSA)就是OSPF接口上的描述信息,例如接口上的IP地址,子网掩码,网络类型,Cost值等等,OSPF路由器之间交换的并不是路由表,而是链路状态(LSA)。 邻居(Neighbor) 两台或多台运行OSPF的路由器在一个公共的网络上形成的基本关系。 但是不一定交换信息 邻接(Adjacency) OSPF只有邻接状态才会交换LSA。 只有发生交换数据关系的设备间叫做邻接 邻居间选择一个交通站DR,负责邻居间交换数据--------------------------------------------------------------------------------------- # 在边界路由器通过再发布方式向内部网段传递默认路由 两个不同协议自治区:RIP 和 EIGRP 路由再发布 两个不同协议自治区:OSPF 和 EIGRP 路由再发布 两个不同协议自治区:OSPF 和 RIP 路由再发布------------------------------------------------------------------                

18,356

社区成员

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

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