用socket api 编了个一个的传输程序,方式为阻塞,程序在局域网上能够正常运行,但奇怪的是我在
调试时发现send函数根本不阻塞,recv到时一直阻塞到直到有数据为止,所以我发现客户端根本不管服务端是否接收,一直发下去,直到发送完毕。这是什么原因,我调试是用我的机器作服务端,我的机器作客户端进行的。高手请指点,马上揭帖!
调试时发现send函数根本不阻塞,recv到时一直阻塞到直到有数据为止,所以我发现客户端根本不管服务端是否接收,一直发下去,直到发送完毕。这是什么原因,我调试是用我的机器作服务端,我的机器作客户端进行的。高手请指点,马上揭帖!
非阻塞模式不是等停的有点像cpu时间片轮转,可以轮流处理多个连接数据,可以用一个线程
处理多个连接,但如果连接较多单个的响应速度就会慢。
一般,本机有缓冲区的,只要它不满,就可一直发下去,
你在局域网,接发的速度都比较快,测试不出效果的
阻塞是异步,,头一次听你说啊,,长见识了。。
-------------------------------------
TO楼主:
send本来就是同步阻塞式,因为你没有使用setsockopt关闭协议栈,所以调用send时,数据很快交给SOCK栈了,以后再由SOCK栈发出去,看起来就没有阻塞。而accept的调用很明显,它死在那里了,直到有联接来。
我的理解:
——————————————————————————————————————————
同步就是一问一答,再问再答,异步就是问的问,答的答。阻塞就是我要接的4k的数据,你一次发过来3k的数据,我都不吊你,继续等;必须满4k,我才继续往下处理。就是发的发,收的收,异步。非阻塞就是基于事件的,你发一次,不管是3k还是4k,我都会接收一次,就是问一次肯定答一次,所以同步。
————————————————————————————————————————
我前面发的是摘自DFW,
《delphi精要》(lxpbuaa(桂枝香在故国晚秋)编写)一书p351,p352写到:单线程模式也称同步模式、非阻塞模式;多线程模式……也称为异步模式、阻塞模式。我也曾经问过他这一点,可惜他给我的解释我没有很明白,上面是我自己的“强制性”理解,不要见笑。可能很简单的道理,但还请各位老兄指点。
只是《delphi精要》
单线程模式也称同步模式、非阻塞模式;多线程模式……也称为异步模式、阻塞模式。--------------------------------------------------
严重不对啊。是否同步或是异步模式跟是否开线程是两码事,怎么能看线程线决定SOCK模式呢?
send recv都是SOCK1.1同步模式的函数,工作模式就像cjf1009(农民程序员) 说的,一问一答了。当程序调用W S A A s y n c S e l e c t注册网络事件时,自动变为异步模式
1 同步阻塞方式:
因为sock阻塞模式中对SOCK函数的调用,阻塞了主线程,比如accept的调用,其它按钮都点不了了,窗口也不响应消息了,所以通常应该把它放到一个线程里去操作,最好是读写线程分开,于是形成了多线程的SOCK模式。2 异步非阻塞模式 该方法可以不需要额外的线程,使用事件驱动
使用WSAAsyncSelect注册网络事件,然后在事件响应里填写响应代码,编程较为简单。这也是MFC 的
CSocket采用的模式,CSocket继承自CAsyncSocket,CAsyncSocket采用的模式看名字就知道了。3 WSAEventSelect
winsock提供了另一个有用的异步I / O模型。和WSAAsyncSelect模型类似的是,它也允许
应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知。由WSAAsyncSelect
模型采用的网络事件来说,它们均可原封不动地移植到新模型。在用新模型开发的应用程序中,也能接收和处理所有那些事件。该模型最主要的差别在于网络事件会投递至一个事件对象句柄,而非投递至一个窗口例程。也就是说一个用窗口函数处理,一个用事件句柄来处理。前者使用窗口消息。后都
通常使用一个句柄数组,信号量的方式。4 重叠IO模型。VC版有小猪手把手教你玩转SOCK模型之重叠IO篇。置顶的贴子。可以去看看。写的不错5 完成端口模型 和重叠IO一样,使用工作线程处理数据。这线程和阻塞模式的线程机制不一样。
----小段
该模型是迄今为止最为复杂的一种I / O模型。然而,假若一个应用程序同时需
要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!但不幸的是,
该模型只适用于Windows NT和Windows 2000操作系统。因其设计的复杂性,只有在你的应用
程序需要同时管理数百乃至上千个套接字的时候,而且希望随着系统内安装的C P U数量的增
多,应用程序的性能也可以线性提升,才应考虑采用“完成端口”模型。要记住的一个基本
准则是,假如要为Windows NT或Windows 2000开发高性能的服务器应用,同时希望为大量套
接字I / O请求提供服务(We b服务器便是这方面的典型例子),那么I / O完成端口模型便是最佳
选择! -----该小段抄自书上的一次回贴,文字数量有限了,更多更详的技术,可以看winsock网络编程技术。
在服务器端接收BUF的时候,如果你设定这次接收为1024个BYTE的话,就会一直等待,直到收到这么多字节为止,不知你发送的时候,是否已经超过你设置的接收范围,如果没有超过,当然是可以继续发送的。
是不正确的,服务端设定1024各byte,如果客户端本次发送只有100个byte,服务端在收到100个byte后
确定客户端再没有数据到达了,它就返回,不会等到超时。比如有一个文件大小为10245byte,我每次发送1024byte,最后一次发送5byte:
客户端最后一次:
buf array[0..1023] of char ;send(soket,buf,5,0);
服务端:
buf array[0..1023] of char ;recv(soket,buf,1024,0);按dotfly(Above the Clouds)地说法,最后都应该死等,实际测试,是最后
服务端接受到5byte就返回了!