很多用Socket 的都用多线程,从CSocket继承CMySocket来处理通讯,每来一个连接,都建立一个CMySocket * pSocket=new CMySocket;来处理同那个客户端的通讯。我这样还有必要用多线程吗?这样能达到多线程的目的吗?可以同时和多个客户端通讯吗?
如果可以,哪位能给我解释一下实现机理。还有WM_TIMER的实现机制。

解决方案 »

  1.   

    是啊,有一个Socket专门负责侦听,而通讯则new了一个新的Socket来处理。可以同时处理多个客户端,因该没有必要再使用多线程了或者使用CSocket的父类CAsyncSocket,功能更强大,不过比较复杂
      

  2.   

    因为每个机器的SOCKET的建立个数是有限制的,不支持大量的用户接入
      

  3.   

    需要用多线程,因为尽管新开了一个Socket,但是此时服务器端的响应会非常慢
      

  4.   

    to  wxbhlj
    98上30个左右,XP上2000个左右,2000上500个左右(我那2000的机器才64内存,可能不准)
      

  5.   

    如果你只连一个server,且没有文件之类的大数据传送,没有必要用多线程当你发现你的socket已经影响到界面的操作,就把它放到后台去
      

  6.   

    to:Rodgu(棒子) 
    可能有多个连接,而且可能是大量文件的传送。这种情况怎样使用多线程??
      

  7.   

    用单线程windows会处理多个通信连接吗?
      

  8.   

    应该可以实现多个用户的连接,不过数量有限,应该与lisent数有关,
    一般accept都是在循环中进行的,一个client连接,会触发server端的
    一个accept,并返回相应的sock值供接收数据,如果还有连接,则再
    触发一个accept,accept数递加,client关闭连接后,accept递减,当
    accpet数目等于lisent的数目时,客户端的请求将被阻塞,直至有新的
    位置,
    以上为个人观点,如果有误,请见良。
      

  9.   

    应该可以实现多个用户的连接,不过数量有限,应该与lisent数有关,
    一般accept都是在循环中进行的,一个client连接,会触发server端的
    一个accept,并返回相应的sock值供接收数据,如果还有连接,则再
    触发一个accept,accept数递加,client关闭连接后,accept递减,当
    accpet数目等于lisent的数目时,客户端的请求将被阻塞,直至有新的
    位置,
    以上为个人观点,如果有误,请见良。
      

  10.   

    如果要广播,或者主播,最好不要用TCP推荐用 UDP连接开着很伤的
      

  11.   

    用多线程来处理多用户是可以的,但是用户多了之后这么多线程切换起来耗费的资源也不得了,所以一般来说服务器程序很少有一个线程(进程)为一个客户端连接服务的。常见的是用Select实现在一个线程里处理多个socket连接,这样能保证多客户连接,而且响应速度比用多线程不慢(因为多线程之间切换要耗费时间)。MudOS甚至只用了一个线程来处理所有的连接,也是用select来监听所有的socket,但是MudOS的性能相当好,这可以证明这种模式的优越性了吧?
      

  12.   

    用TCP服务器端需要用一个监听口,此后来一个客户请求就需要开一个连接.如果用UDP就可以只用一个口了.但是用UDP容易丢包,所以需要有服务器超时重发和客户收到确认的协议.这可以由你自己定.
      

  13.   

    如果确实需要不停地建立和释放连接,可以建一个连接SPOOL,效率会大大提高.当然会更麻烦一点.
    我不知在.NET下有没有可能将SPOLLING这部分工作做得简化一点.
      

  14.   

    我希望所有的客户端在开着的时候都与Server保持连接,随时可能传送文件。当然,这就可能发生Server同几个Client同时传送文件的可能。用UDP是肯定不行的。顺便问一下select是什么东东呀?
      

  15.   

    随时可能传送文件,一次传送数据量是多少?实时性要求高吗?你确信必须用TCP吗?
    select是Berkley Socket 函数,会block的,在WINDOWS这样的消息驱动机制下可能不太好用。
      

  16.   

    讨论一下API吧,这样更有帮助
      

  17.   

    可是别人问的是CSocket呀. :)
      

  18.   

    传送数据的量很难说,应该说是没有限制,如果大的话,就让它一直在传。但不要影响别的客户端的文件传送请求。我现在发现,如果一个客户端block的话,界面就刷新不了了,可想而知这时候别的可户端请求能响应吗?!
      

  19.   

    所以说你不要用TCP了,就用UDP吧。我用TCP做的程序也遇到过类似的问题的,就是用MSDN里的chat server 和client 例程改编的。长期运行中有时会对界面操作不反应,也不刷新,好象是BLOCK了,当时我一气之下改用网络共享文件来通讯,虽然有时会出现文件锁冲突,但这是可以重试的。
    网络文件在98下可以在虚拟盘上,但在2000下好象不能设虚拟盘了。
      

  20.   

    CSocket好像不支持多线程,我试了很多次都不成功,后来我自己写了一个类封装winsock api才可以用多线程,也不会降低效率,通讯的瓶颈在建立tcp连接,不过用多线程非常不容易调试,一旦出微小的错误,也很难查。最好别用多线程。
      

  21.   

    to:AroundClockDancer(夜行人) 
    用UDP来传送文件?能保证可靠吗?to:  stonespace(stonespace) 
    能把你的类发给我看看吗?
      

  22.   

    刚在网上看了段文章,贴出来大家参考参考:但是在把SOCKET类和多线程一起使用的时候,需要注意到的一个问题是关于在线程中的参数的传递。根据Microsoft文档的技术说明,如果向一个线程传递一个CWnd对象的时候是会发生不可预知的错误,而CSocket类实际上在内部绑定了一个CSocketWnd类,而该类是从CWnd中继承的,所以在多线程设计的时候,一定不能够传递一个CSocket对象到一个新的线程里面,但是可以传递句柄。 ---- 另外,CSocket对象所产生的消息是发送给和该CSocket对象相绑定的CSocketWnd窗口的,如果在主线程中已经创建了和用户通讯的SOCKET对象,而把它传递给一个新开的线程中去使用的话,其实该SOCKET对象的消息还是会都发送到主线程而不是新的子线程中,这样新开的线程实际上也没有多大的作用。 
      

  23.   

    to  wxbhlj(波波)
    我的那个类是帮公司写的,管得严,拿不出来,不过很简单,只是封装了socket地句柄而已。
      

  24.   

    服务器如不用多线程处理,也可以支持多多客户端连接(至少200个)。服务器端为每个客户端连接建立接受Socket,最好用动态链表保存。重载OnReceive函数,在此函数中处理服务器请求。
      

  25.   

    bobo to:AroundClockDancer(夜行人) 
    用UDP来传送文件?能保证可靠吗?
    re:不可靠的服务可以靠高层协议来达到可靠,包括数据完整性校验,收到确认,超时重发等等,这些协议你都可以自己来定的。你可以自己定义数据包的格式。
      

  26.   

    to: Samprase()
    虽然CSocket的事件驱动能做到类似多线程一样,可它在接收或发送大量数据时还是会造成界面元素响应很慢!to:AroundClockDancer(夜行人) 
    呵呵,那样处理起来不就更复杂了吗?!
      

  27.   

    如果只是传输文件,不加控制,可以直接用现有的高层协议,MFC有CInternetFile之类的类也可以用用的.你自己用FTP协议.
      

  28.   

    还没完全挂起来,起码鼠标还是能响应的,只是象爬的一样:)
    还在研究在多线程中用CSocket,有结果会帖上来和大家分享的。我想在OnReceive()中响应,然后再启动一个线程来接收数据。不知道可不可以,回家试试。
      

  29.   

    请问如何从客户端用WIN SOCKET发一个注册信息(如姓名、ID、年龄)到服务端,如果用一个字符串(eg: "name,id,age"),那到服务端双如何把它们分开,我想用Split(),结果编译时告之无此函数,真不知该如何是好?还有一个小问题
    “有没有一个能获得一个数组长度的函数”,谢谢!
      

  30.   

    使用多线程的情况:服务器端:
    1.客户端用户数太多( 大于200 ),但此时最好也不要一个客户就开一个线程处理,原因上面的贴子已经说过了。
    2.需要传送大量的数据或文件
    3.一般说来,服务器端至少会有三个线程存在: 一个是主线程,一个是侦听端口的线程,再有一个就是与客户端通信的线程。客户端:
    1.连多个个server,
    2.有文件之类的较大数据传送
    3.发现socket已经影响到界面的正常操作
    如果要得到满意的执行速度,最好还是别用MFC中的Socket类,建议自已使用WIN SOCKET API封装一个类。
      

  31.   

    每个连接都有一个CMySocket对象与之对应,各个对象独立工作,相应连接方发送的数据由对应的对象接收
      

  32.   

    我也碰到了阻塞的问题!!!我的程序中使用CSocket来在两个进程中传输数据,但是发现在使用中client端
    经常被阻塞了,只要推出服务器程序,client端又回复正常!不知道有没有好的解决方法??
      

  33.   

    to:all
    谢谢大家的支持,问题算是解决了。但不知道会不会出现负面影响。
    我从CWinThread继承一个类CSocketThread,在里面加上CMySocket的一个成员。
    在Accept的时候,就把m_hSocket传递给CSocketThread中的CMySocket.Attach(m_hSocket),然后启动这个线程。这样不再影响我的界面,但没来一个连接,我都要开一个线程来和它通讯,不知道多的时候会不会对系统的性能影响很大。就算最多200个吧。
      

  34.   

    用多线程是不错的解决,不过考虑把这些功能封在COM+组件里,是不是就相当于有SPOOLING功能了呢?不过我还没动手做过,请做过的人指教!
    另外,如果你的线程阻塞或挂起来,那就会永久占有资源呀!结果是线程越来越多了。所以多线程只是延缓了问题而已。当然多线程对一个服务器程序来说还是很有益的。
    关键是如何探测阻塞或挂起的线程,强制处理它。
      

  35.   

    可以监听线程的heart beat,即定时向主线程报告自己的情况。如果没有heart beat了就把它撤消。尽可能做得GRACEFUL一点。跟工控里的watch dog 是一样的道理。
      

  36.   

    to::AroundClockDancer(夜行人) 谢谢你的支持,这两天不想写了。有空可以聊聊。my oicq:24310608  email:[email protected]
      

  37.   

    更正,前面我说的两处SPOOL应为POOL,意思是建立连接池,减少反复建立很撤消连接的次数。属口误,请大家谅解!