异步Socket和多线程并没有矛盾。异步Socket的优势在于可以在一个线程中处理很多Socket的请求,因为Socket的读写操作很多时间都花费在网络上,所以线程在发出异步读写操作后可以去处理别的Socket的请求。对于典型的异步Socket构造的服务器,一个线程也只能处理不到64个Socket对象的请求,这种情况下仍然需要多线程的支持。

解决方案 »

  1.   

    本身异步的Socket就是多线程的,系统开另一个线程去处理读写,让你的主线程可以继续执继其它处理,等异步操作线程完成了再返回执行结果,只不过那个线程由系统管理罢了。楼上所说异步线程只能处理不到64个Socket对象的请求,有根据吗?
      

  2.   

    我上面所说的“一个线程”,是指你的程序中负责处理socket请求的线程。我说的典型的异步Socket构造的服务器,是指没有基于IOCP使用异步 Socket的服务器,这种程序一般都是使用select、WSAWaitForMultipleEvents这种API,select调用中需要一个数组,这个数组长度默认是64,当然,你可以通过先define FD_SETSIZE 的方式改变这个值,但我总觉得这样很不爽,而且也没这么做过,不清楚是否真的可以。而且select是轮询的,效率上会稍微差些。对于WSAWaitForMultipleEvents,其实就是一个WaitForMultipleEvents, 里面那个HANDLE数组最多也只能容纳64个元素,再加上你自己需要一两个控制用的event对象,也就不到64个了。这种情况下,如果你想处理64个以上的socket连接,就需要再开一个线程。
      

  3.   

    我上面所说的并没有提到WSAAsyncSelect这种方式,我始终认为通过窗口的消息队列来处理socket请求只适用于对效率没有要求的场合
      

  4.   

    C#的异步Socket使用的WIN的完成端口模式,这是目前win最完善的Socket模式,见<<windiows网络编程>>2版.
    我想说使用它是不需要编程者在写程序的时候使用多线程的技术来做什么接受啊,发送啊等等的,但是那本书在介绍'C#的异步Socket'的编程时竟然还是使用多线程技术的和同步的几乎一样,这是误认子弟啊.差点将我带入歧途,好的方法不敢独享贴出来大家看看,是不是这么回事.我做的测试:两台PC2.4G 512M 分别建立客户端,服务器,客户端执行 连接->发送(100k)(异步)->接受到服务器回复数据后关闭(异步)
    服务器执行 接受连接(异步)->接受数据(异步)->回复数据(异步)
    客户端执行循环5000次,循环中没有使用延迟技术
    测试通过,没有任何错误,同时服务器的CPU占用只有3-4%,要是同步的服务器早就晕了.源代码请使用论坛的查询功能关键字是"为了不让<<Visual C#.Net 核心网络核心编程>> 误导大家对异步Socket"
      

  5.   

    对于数据量大的、同步请求多的、接受到关闭单位时间内要有其它处理的都必须要用同步,异步只合适于小型的chat 之类的大的系统还是推荐负载平衡+同步(早期apache 还是每请求一进程而不是线程哩)在server 级别的平台上,每进程1000线程同时是很正常的事,并且在调度上不会有很大的性能影响,这是SERVER 级别首要的优势
      

  6.   

    线程级别的Cpu时间执行共享和异步执行是完完全全两码事!
      

  7.   

    为什么说WSAAsyncSelect这种通过窗口的消息队列来处理socket请求只适用于对效率没有要求的场合呢?能说明一下么?我正在用WSAAsyncSelect做FTP CLIENT
      

  8.   

    你说的那本书我倒是没看过,不过我确实见到过有些书在介绍异步socket时就是开一个线程然后等待一个socket的异步消息,而不是一个稍有使用价值的服务器模型,大概是为了让例子简单一些。关于阿里的观点,我不太同意。
    我不太了解Unix/Linux操作系统的情况,不知道它的线程是否可以轻量级到开销比Windows低很多的程度,但对Windows操作系统而言,大量的线程确实会有比较大的开销,而且如果是用同步Socket,你用一个线程处理一个Socket的话只能实现一个单工操作的系统,如果想实现全双工,对每个Socket需要有两个线程处理,这样系统开销就更大了。而对于异步操作,是没有这种问题的,一个活动线程在网卡发送数据时,完全可以去做别的更有意义的事,比如数据处理这种真正需要CPU资源的操作,而不是毫无意义的等待网卡这种慢速设备发送数据。早期apache对每一个请求都是一个进程处理,这是因为Unix/Linux的进程实现和Windows的进程不一样,Windows的进程是重量级的,而Unix/Linux上的进程是轻量级的,其开销和Windows下的线程类似,所以一个请求用一个进程处理也是可以接受的。至于我对WSAAsyncSelect的观点,很大程度上是依赖于我的推断,而不是基于实际测试,如果说错了希望大家指出来。WSAAsyncSelect操作的结果是通过Windows的消息通知给应用程序,而一个窗口的消息队列中还充斥着很多别的与数据毫不相关的消息,这样,随随便便的一个消息的处理就可以影响你对一个网络数据发送/接收操作的及时响应。而且如果界面程序中某个地方有一个比较长的循环,其中只用PeekMessage处理了界面更新的消息,那这段时间内系统发给你的Socekt消息就不会得到处理,这对于一个对传输效率要求比较高的场合显然是无法接受的。当然了,对于一些的客户端系统,如果不想为网络操作开一个线程,而且对传输效率的要求也不高,用WSAAsyncSelect还是很方便的。
      

  9.   

    我以前使用同步Socket是用bcb开发的,当访问量一上去,程序就崩溃了:( 没办法只好多使用了很多服务器,造成程序的性能低下,Socket是网络程序的关键技术,请认真选择Socket的类型进行开发(没办法以前不懂有那么多种Socket类型),它和你程序的健壮性有直接关系.分不够可以加 欢迎讨论.
      

  10.   

    win Socket 我所知道的模型
    1 阻塞模型(同步模式)
    2 select模型(异步模式)
    3 WEAAsyncSelect模型(异步模式)
    4 WSAEventSelect模型(异步模式)
    5 重叠模型(异步模式)
    6 完成端口模型(异步模式)困了,下会在贴他们的介绍,以及测评.
      

  11.   

    http://www.microsoft.com/mspress/books/sampchap/5726a.asp
      

  12.   

    异步: 为了实现多用户
    多线程: 为了提高程序速度
    虽然会增加系统负担,但是你的程序速度变快了,对于server来说,这是很合理的
      

  13.   

    http://www.microsoft.com/mspress/books/sampchap/5726a.asp
    是这些模型的测评报告,以及详细描述,感谢 sxbyl(会用Windows的白菜)我想无论在任何应用情况下
    完成端口模型(异步模式)
    都是最好的,不知道大家对此有何质疑?
      

  14.   

    还想问一下如果使用UDP是否还有必要使用异步或同步?