可恶的Winsock就是不干活-可以再加分(100分)

  • 主题发起人 主题发起人 lhz
  • 开始时间 开始时间
L

lhz

Unregistered / Unconfirmed
GUEST, unregistred user!
M$的东东,真是“不怕做不到,只怕想不到”,出起错误来不管你想不想得
到,害你没商量。

先说一个简单的:关于异步Socket的问题。
M$的Win32SDK说可以用WSAAsyncSelect实现异步Socket。但是,我用尽各
种参数都没法让socket的sendto成为异步的。它总是要等到所有数据全部发
送完之后才返回。我用ioctlsocket也不行,它照行不误。我也用ICS的
WSocket控件和NMUDP控件测试过,都没法实现异步,虽然它们的文档都声称
可以异步的。sendto就真的不能异步吗?

WSAAsyncSelect不行,我就换WSASocket/WSASendTo。该死的Win32API要求
我必须在调用WSASendTo的同一个线程里面调用SleepEx/WaitForXXXEx系列
函数才行。我Sleep了,还怎么更新界面啊?没办法,只好新开一个线程,并
想方设法把参数传到线程里面。现在WSASentTo倒是异步了--一调用就返回,
也能正确响应回调函数。但新问题又来了--我在100Mb的SwitchHUB局域网上
发送一个16KB的包竟然要1秒多!!!!又试了上面的sendto,也是这效果。
即使用同步的sendto,也只有这速度。

100Mb的SwithHUB不行我换10Mb的共享式HUB。在10Mb共享式HUB上它倒是跑
得很欢,可是更怪的问题又来了:

我用3台机器来测试,分别以A,B,C表示。我用UDP的广播方式发送数据,
结果如下:

B发送,A、C收:正常
C发送,A、B收:正常
A发送,B、C收:C正常,B大量丢包(丢的比收到的多得多)
还没来得及用更多的机器测试。再测试不知还会出什么问题!!!

不知谁用成功过UDP广播的异步发送?我真是要气死了!!!
 
异步难做得, 别开个线程能解决吗?
 
波特率设的是否太高?
 
老兄!UDP不是流式的,也没有流控,哪里来的异步发送的概念呀!

 
to wuyi:
开线程很浪费资源的,而且有线程就必须考虑线程间数据的传递.
同步问题很头痛.而且,95对多线程信号量的支持很差.如果程序
要在95使用,就不想用多线程--信号量常死,线程调度也常出问题.
to Jams:
这好象和波特率没有关系?
to pegasus:
异步和流控好象没有关系?异步是与非阻塞相似的概念,与流的概
念似乎差得远了一点.
to all:
现在发现,UDP的广播包在Switch HUB上发送得很慢,而在共享使HUB
上就很快.而点对点发送就没有这个问题.不知各位是否遇到过这种
问题?我现在需要广播,不知如何是好.总不能要求客户都换成共享式
HUB啊?
 
To lhz:

是啊:之所以要用阻塞或者异步就是因为一个动作的完成需要一段moderated time,(相当长的时间),但是UDP的发送没有这个问题,因为不需要对方的确
认,只要数据送到网卡就算成功了。

TCP这样的可靠的流式系统就不同了,所以要引入什么阻塞和非阻塞

 
to pegasus:
这种说法是错误的.因为网卡通常都有一块内存作为IO的缓冲区(如果是最
低级的那种NE2000兼容,这块缓冲区可能由驱动程序在内存中开).当数据
送到缓冲区后,要经过一段时间才能发送完成.由于以太网是竞争发送的,所
以发送所需要的时间是不可预测的,其他类型的网络也有类似情况.异步的
作用就是在网卡工作的时候让CPU干其他的工作,而又不要发送更多的数据
把网卡的缓冲区撑破了.

上面只是描述了链路层的情况.对TCP/IP协议来说,整个体系是一个栈结构,
每层都与上面的情况类似.比如说,IP->链路层(一般是网卡驱动程序),
UDP->IP,SOCKET->UDP等等.也就是说,每层都需要异步/同步接口.如果某
一层没有提供异步接口,以上的层次是不能提供异步接口的.TCP在这里和
UDP根本没有区别,等待对方的确认和等待网卡发送数据在API上是反映不
出来的.况且TCP的实现并不是要等待对方确认之后才发送下一个数据包--
这样的实现效率太差了,不可接受--TCP用一种称之为滑动窗口的技术,在
对方确认信息到来之前就可以接受新的发送任务.所以,一般的实现都是在
网卡发送完数据后就通知SOCKET数据已经发送完成.这样与UDP就没有实现
上的区别了.

现在的问题是:在发送数据时,WINSOCK一定要等到数据在网卡上发送完了才
返回.这显然不是异步的!!!!

另一个问题也相当怪:当一个进程使用多个线程时,如果线程间用信号量同步,
则95/98很容易死机.即使不死,系统的整个性能也降到不可忍受的地步!!!
而NT就没有问题.可是客户偏偏只能用95!!!!
 
hehe, 怪我粗心大意, 确实可以用异步,但是一般在UDP的时候是不需要的

>如果某一层没有提供异步接口,以上的层次是不能提供异步接口的.
其实也是能够提供的

>TCP在这里和UDP根本没有区别,等待对方的确认和等待网卡发送数据在API上是
>反映不出来的.况且TCP的实现并不是要等待对方确认之后才发送下一个数据包
>--这样的实现效率太差了,不可接受--TCP用一种称之为滑动窗口的技术,在
>对方确认信息到来之前就可以接受新的发送任务.所以,一般的实现都是在
>网卡发送完数据后就通知SOCKET数据已经发送完成.这样与UDP就没有实现
>上的区别了.
还是有区别的,滑动窗口中的内容都要等到对方的确认来了之后才能滑动
下去,不然本地的发送就会被阻塞住,其次TCP也不一定是立刻发送用户程
序送来的数据,比如它可能会等待一小会儿看看能不能凑足一个大一点的
包来发送,如果等了一会儿没等到那么就只好发送出去。还有如果对方的
程序一直不接收,对方的TCP就会通知发送者不要继续发送,等等。TCP中
处理的比UDP复杂许多。

通常,UDP的发送是不会阻塞的,如果出现你说的网卡缓冲区阻塞的情况,
那么UDP的发送就失败而已,这和TCP是不同的。

不过不知道你的系统到底怎么回事,即使是网卡发送出数据也不需要很长
时间。
 
to pegasus:
多谢您的回答.但是我的问题仍然没有解决.不管是UDP还是TCP,当网卡
发送数据时我总是需要CPU执行别的计算任务.

现在我发现问题是:Switch HUB上广播时,发送速度非常慢,而点对点就没有问题.
共享式HUB也没有问题.不知是否有人遇到过类似问题?
 
Do anyone else want to say any more?
 
那么说是因为Switch方式的Hub不适于广播?
当发现广播请求的时候,Switch是不是需要逐个同其他的每个网卡
Switch过去一次?这样的话肯定要慢多了,:(
 
可能是这个原因。
这岂不是严重影响了现在的多媒体应用?
这些应用通常要求高效的广播传输。

而且,对正日益广泛使用的client/server体系,
switch HUB似乎没有多少优势。这样岂不是要淘
汰switch HUB了?
 
多人接受答案了。
 
后退
顶部