用socket api 编了个一个的传输程序,方式为阻塞,程序在局域网上能够正常运行,但奇怪的是我在
调试时发现send函数根本不阻塞,recv到时一直阻塞到直到有数据为止,所以我发现客户端根本不管服务端是否接收,一直发下去,直到发送完毕。这是什么原因,我调试是用我的机器作服务端,我的机器作客户端进行的。高手请指点,马上揭帖!

解决方案 »

  1.   

    不会吧,我也用API没出现问题啊, 把你的部分代码贴出来看一下。
      

  2.   

    阻塞模式也称为异步模式,是等停的一个连接的数据没有发送完毕,sever端就等在那里,不响应其他连接,这样的好处是一对一传送较稳定client数据传送发应速度快,但每个连接服务器要创建一个线程,耗费系统资源多。
    非阻塞模式不是等停的有点像cpu时间片轮转,可以轮流处理多个连接数据,可以用一个线程
    处理多个连接,但如果连接较多单个的响应速度就会慢。
      

  3.   

    >>调试时发现send函数根本不阻塞
    一般,本机有缓冲区的,只要它不满,就可一直发下去,
    你在局域网,接发的速度都比较快,测试不出效果的
      

  4.   

    哈哈,,, cjf1009(农民程序员)  
    阻塞是异步,,头一次听你说啊,,长见识了。。
    -------------------------------------
    TO楼主:
    send本来就是同步阻塞式,因为你没有使用setsockopt关闭协议栈,所以调用send时,数据很快交给SOCK栈了,以后再由SOCK栈发出去,看起来就没有阻塞。而accept的调用很明显,它死在那里了,直到有联接来。
      

  5.   

    呵呵,关于阻塞、非阻塞、同步、异步我确实不是特别熟,基本是人云亦云加上自己的强制性理解。希望上面两位老兄多多指教。
    我的理解:
    ——————————————————————————————————————————
    同步就是一问一答,再问再答,异步就是问的问,答的答。阻塞就是我要接的4k的数据,你一次发过来3k的数据,我都不吊你,继续等;必须满4k,我才继续往下处理。就是发的发,收的收,异步。非阻塞就是基于事件的,你发一次,不管是3k还是4k,我都会接收一次,就是问一次肯定答一次,所以同步。
    ————————————————————————————————————————
    我前面发的是摘自DFW,
    《delphi精要》(lxpbuaa(桂枝香在故国晚秋)编写)一书p351,p352写到:单线程模式也称同步模式、非阻塞模式;多线程模式……也称为异步模式、阻塞模式。我也曾经问过他这一点,可惜他给我的解释我没有很明白,上面是我自己的“强制性”理解,不要见笑。可能很简单的道理,但还请各位老兄指点。
      

  6.   

    cjf1009(农民程序员)理解的不错
    只是《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网络编程技术。
      

  7.   

    阻塞方式就是同步啦;在服务器端接收BUF的时候,如果你设定这次接收为1024个BYTE的话,就会一直等待,直到收到这么多字节为止,不知你发送的时候,是否已经超过你设置的接收范围,如果没有超过,当然是可以继续发送的。
      

  8.   

    感谢各位,就我地问题我非常同意aiirii(ari-淘金坑) ,Delphityro(不吃腥的猫) 的观点,这个问题对我程序没有影响,只是搜遍论坛都没发现有人问,特提出来!我认为诸塞也应该是同步的,但: dotfly(Above the Clouds) 的回答:
    在服务器端接收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就返回了!