WSAEventSelect 的 发送问题

BOYGUARD110 2006-01-18 02:48:15
如下的 code 为什么 不能 连续发送 ??

while(1)

{
WSAResetEvent(h1);

// 等待 网络事件
DWORD r2 = WSAWaitForMultipleEvents(1, EventArray,FALSE,WSA_INFINITE,FALSE);



WSANETWORKEVENTS NetworkEvents;

// 获得 网络事件
WSAEnumNetworkEvents(s1,h1,&NetworkEvents);
if(NetworkEvents.lNetworkEvents & FD_WRITE )
{
char data[100]={"hello socket"};
send(s1,data,100,0);

}
}

//////////

运行以上code的现象是:

第一次 是可以 发送的 ,

while 执行 第 2 次的 时候 就会 永远 阻塞在 WSAWaitForMultipleEvents 函数的 地方


请问这是为什么??

谢谢


...全文
229 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
BOYGUARD110 2006-01-22
  • 打赏
  • 举报
回复
谢谢 各位兄弟,虽然还有问题,我会另开一贴,欢迎继续指导
BOYGUARD110 2006-01-20
  • 打赏
  • 举报
回复

各位兄弟再给点回音啊 !!!

jazy 2006-01-20
  • 打赏
  • 举报
回复
框架 2

简述: 先 调用 WSAWaitForMultipleEvents 对网络事件进行等待 ,

待 出现 FD_WRITE 的 信息后 , 再 调用 send 函数

这里我的理解与你不同,我看msdn的解释,连接建立后FD_WRITE一定处于signal状态,可以用send(就是说这第一次send之前等不等FD_WRITE是无所谓的),但这时send的结果不一定成功,
(1)如果成功,马上就可以再用send,不需要也等不到下一个FD_WRITE。
(2)如果失败且原因是block,就必须等下一个FD_WRITE,以决定是否可以进行下一次send。
因此我认为你的两种框架需要组合在一起,并不存在并列的两种选择。
yingpf 2006-01-20
  • 打赏
  • 举报
回复
不懂,帮顶
jazy 2006-01-19
  • 打赏
  • 举报
回复
send:即使出现错误WSAEWOULDBLOCK,当次send还是会完全成功的,只不过在得到FD_WRITE事件前,不允许下次send

recv返回SOCKET_ERROR?那么getlasterror看看错误原因吧,这种情况没见过。我的理解只要收到了FD_READ,recv就不该不成功的,奇怪。
BOYGUARD110 2006-01-19
  • 打赏
  • 举报
回复

jazy() ( )

你好:

根据网上的一些代码 和 我的 理解 ,关于 send 和 recv 有两种使用的 框架:

以 send 函数 为例 如下:

请你看一下是否正确 或者 存在 理解上的 问题, 我是有些不明白?


//////////////////
框架 1

简述: 先 调用 send 函数, 再调用 WSAWaitForMultipleEvents 对网络事件进行等待


int r = send( )
if( r == SOCKET_ERROR )
{
r = WSAGetLastError()
if( r == WSAEWOULDBLOCK )
{

WSAWaitForMultipleEvents

WSANETWORKEVENTS NetworkEvents;

WSAEnumNetworkEvents(s1,h1,&NetworkEvents);


if(NetworkEvents.lNetworkEvents & FD_WRITE )
{
// 执行到这里 说明 前面的 send 已经执行成功了 ,对吗 ??

}


}


}

//////////////////
框架 2

简述: 先 调用 WSAWaitForMultipleEvents 对网络事件进行等待 ,

待 出现 FD_WRITE 的 信息后 , 再 调用 send 函数






WSAWaitForMultipleEvents

WSANETWORKEVENTS NetworkEvents;

WSAEnumNetworkEvents(s1,h1,&NetworkEvents);


if(NetworkEvents.lNetworkEvents & FD_WRITE )
{
// 执行到这里 说明 此时 如果 此时 调用 send , os 保证 会成功 对吗 ??
int r = send( )
}


}


}



谢谢





nuaawenlin 2006-01-18
  • 打赏
  • 举报
回复
WSAResetEvent(h1);

///////////////////////////
WSAResetEvent(EventArray[0]);

应该复位以传信的事件

发现你没有把事件数组和单个事件结合起来

写成

DWORD dwIndex;
dwIndex = WSAWaitForMultipleEvents(。。。。);
dwIndex -= WSA_WAIT_EVENT_0;//注意这里

WSAResetEvent(EventArray[dwIndex]);

这个方式比较好

BOYGUARD110 2006-01-18
  • 打赏
  • 举报
回复
为什么 第2次 FD_WRITE 的 状态 等不到呢 ?
BOYGUARD110 2006-01-18
  • 打赏
  • 举报
回复
lixiaosan(小三) , 你好:

我的code很简单,是 client 端的 , 就是我贴出来的那些,

就 1 个 event 和 1 个 socket ,

因此直接 把 event 的 句柄 h1 传给 WSAResetEvent 函数

我的问题是, 为什么 WSAWaitForMultipleEvents 无法 返回了

( 我使用的 WSA_INFINITE 无线等待),

这样 我无法得到 error code ,

谢谢







BOYGUARD110 2006-01-18
  • 打赏
  • 举报
回复

jazy() ( ) 信誉:100
send返回WSAEWOULDBLOCK了吗?如果没有返回WSAEWOULDBLOCK那么不再收到FD_WRITE是正常的,不一定非要等待FD_WRITE作为发送数据的前提吧?
=========================================================

你好:

按照你的方法,

我试了一下,可以了发送了,

但是 如何知道 发送走了 多少字节呢 ?

另外,按照同样的顺序, 如果 调用 recv 函数 那如何知道 到底收到多少数据呢?

因为 recv 的 返回值 是 实际 收到的 字节数,

但是 在异步情况下, 返回值 是 SOCKET_ERROR ,

这样就没有办法知道 recv 到底 收到了 多少字节数据了?

谢谢












lixiaosan 2006-01-18
  • 打赏
  • 举报
回复
是不是重置的时候index不对?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsawaitformultipleevents_2.asp
看看WSAWaitForMultipleEvents的返回值的处理

HANDLE EventArray[1] = h1;
==>
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];

EventArray[1] = WSACreateEvent();

DWORD dwIndex;
dwIndex = WSAWaitForMultipleEvents(。。。。);
dwIndex -= WSA_WAIT_EVENT_0;//注意这里

WSAResetEvent(EventArray[dwIndex]);
lixiaosan 2006-01-18
  • 打赏
  • 举报
回复
哦。。你第一句就是WSAResetEvent,,我看掉了,以为你没有用WSAResetEvent。。。。抱歉。。
BOYGUARD110 2006-01-18
  • 打赏
  • 举报
回复

lixiaosan(小三) , 你好:

我前面的code 大概 是这样的


SOCKET s1 = socket(AF_INET,STREAM , 0);

HANDLE h1 = WSACreateEvent();

WSAEventSelect(s1,h1.FD_WRITE);

HANDLE EventArray[1] = h1;


while(1)
{


//
// 加上这一句 主要是因为 觉得,每次WSAWaitForMultipleEvents 返回
//
// 会把 那个 event h1 置为 signaled 状态,所以 给他 复位一下
//
WSAResetEvent(h1); //

}

再帮忙分析一下,谢谢



lixiaosan 2006-01-18
  • 打赏
  • 举报
回复
WSAResetEvent ???
mynamelj 2006-01-18
  • 打赏
  • 举报
回复
WSAWaitForMultipleEvents这个函数不能自动重置,你要手工重置
jazy 2006-01-18
  • 打赏
  • 举报
回复
send返回WSAEWOULDBLOCK了吗?如果没有返回WSAEWOULDBLOCK那么不再收到FD_WRITE是正常的,不一定非要等待FD_WRITE作为发送数据的前提吧?

18,356

社区成员

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

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