CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

高分释疑!CSocket 高手请进!

楼主wxbhlj(波波)2002-09-09 13:27:20 在 VC/MFC / 基础类 提问

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

1 楼antshome(我好累)回复于 2002-09-09 13:33:31 得分 5

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

2 楼wuxuan(真心英雄)回复于 2002-09-09 13:38:19 得分 5

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

3 楼wxbhlj(波波)回复于 2002-09-09 13:39:52 得分 0

大量指多少个以上?Top

4 楼ashanm()回复于 2002-09-09 14:32:06 得分 5

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

5 楼azlza(微笑)回复于 2002-09-09 14:37:27 得分 10

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

6 楼Rodgu(棒子)回复于 2002-09-09 14:50:25 得分 5

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

7 楼wxbhlj(波波)回复于 2002-09-09 16:04:50 得分 0

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

8 楼wxbhlj(波波)回复于 2002-09-09 16:07:32 得分 0

希望大家多多指教,我会继续加分的,上面几位朋友都有分!先谢过了。Top

9 楼happymgp(小黑)回复于 2002-09-09 16:10:49 得分 0

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

10 楼wxbhlj(波波)回复于 2002-09-09 17:08:45 得分 0

up......Top

11 楼glhorse(happy day)回复于 2002-09-09 17:32:07 得分 10

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

12 楼glhorse(happy day)回复于 2002-09-09 17:33:19 得分 0

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

13 楼mooncat2000(三脚猫)回复于 2002-09-09 17:48:55 得分 0

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

14 楼timeguest(三少爷)回复于 2002-09-09 17:59:20 得分 10

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

15 楼AroundClockDancer(夜行人)回复于 2002-09-09 18:41:46 得分 30

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

16 楼AroundClockDancer(夜行人)回复于 2002-09-09 19:05:23 得分 0

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

17 楼wxbhlj(波波)回复于 2002-09-10 12:40:31 得分 0

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

18 楼AroundClockDancer(夜行人)回复于 2002-09-10 13:51:56 得分 0

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

19 楼ypos(叶开)回复于 2002-09-10 14:13:39 得分 0

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

20 楼AroundClockDancer(夜行人)回复于 2002-09-10 14:17:48 得分 0

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

21 楼wxbhlj(波波)回复于 2002-09-10 14:41:06 得分 0

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

22 楼AroundClockDancer(夜行人)回复于 2002-09-10 22:08:51 得分 0

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

23 楼stonespace(stonespace)回复于 2002-09-10 22:28:58 得分 10

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

24 楼wxbhlj(波波)回复于 2002-09-11 13:59:39 得分 0

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

25 楼wxbhlj(波波)回复于 2002-09-11 15:34:56 得分 0

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

26 楼stonespace(stonespace)回复于 2002-09-11 20:42:38 得分 0

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

27 楼Samprase()回复于 2002-09-11 22:47:00 得分 0

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

28 楼AroundClockDancer(夜行人)回复于 2002-09-11 23:46:28 得分 0

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

29 楼wxbhlj(波波)回复于 2002-09-12 10:31:14 得分 0

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

30 楼AroundClockDancer(夜行人)回复于 2002-09-12 13:26:25 得分 0

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

31 楼AroundClockDancer(夜行人)回复于 2002-09-12 13:38:06 得分 0

波波:不是响应很慢,而是就好象是挂起来了吧?Top

32 楼wxbhlj(波波)回复于 2002-09-12 14:29:51 得分 0

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

33 楼daveyyu(DaveyYu)回复于 2002-09-12 15:04:04 得分 0

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

34 楼sunheart(深蓝)回复于 2002-09-12 15:54:43 得分 0

棒子对。但我也做过这样的程序(和你说的一样的方法),连接煤矿服务器获取大量数据,还可以。不到万不得已,可以不用多线程,以免增加软件开发成本。Top

35 楼xtky_limi(窗外细雨)回复于 2002-09-12 17:09:59 得分 10

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

36 楼scjb79(叶飞)回复于 2002-09-12 17:21:52 得分 0

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

37 楼dou_ya(豆芽菜)回复于 2002-09-12 18:26:22 得分 0

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

38 楼wxbhlj(波波)回复于 2002-09-13 10:39:25 得分 0

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

39 楼AroundClockDancer(夜行人)回复于 2002-09-13 23:11:03 得分 0

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

40 楼AroundClockDancer(夜行人)回复于 2002-09-13 23:13:30 得分 0

另外,我觉得在你写多线程代码前应该先做这种分析。先分析,审核,再设计,审核,编码,是不是?Top

41 楼AroundClockDancer(夜行人)回复于 2002-09-14 17:57:01 得分 0

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

42 楼wxbhlj(波波)回复于 2002-09-19 11:26:53 得分 0

to::AroundClockDancer(夜行人)    
   
  谢谢你的支持,这两天不想写了。有空可以聊聊。my   oicq:24310608     email:oicqemote@sina.comTop

43 楼lchy20cn(小猫Pisceslc)回复于 2002-09-20 17:52:56 得分 0

好帖子,先标志!Top

44 楼AroundClockDancer(夜行人)回复于 2002-09-22 17:11:35 得分 0

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

相关问题

  • 请CSocket高手来释疑!!!!!!!!!!!!!!
  • ☆☆☆☆☆释疑,解惑!高手请进!!!!!!☆☆☆☆☆☆☆
  • 请您释疑
  • System.out.println()释疑
  • 100分,高手请进,有关CSOCKET
  • 请老鸟高手大虾看图!释疑!给分!在线等候!
  • String用法释疑
  • CSocket
  • 关于MSComm控件,请达人进来释疑.实在找不到相关说明
  • 100分,几个有关CSocket的问题,高手请进!急!!

关键词

  • 多线程
  • 线程
  • 连接
  • 客户
  • 服务器
  • 文件
  • socket
  • 数据
  • 函数
  • 通讯

得分解答快速导航

  • 帖主:wxbhlj
  • antshome
  • wuxuan
  • ashanm
  • azlza
  • Rodgu
  • glhorse
  • timeguest
  • AroundClockDancer
  • stonespace
  • xtky_limi

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo