高分释疑!CSocket 高手请进!
很多用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




