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

关于写即时通讯的一些基本问题!

楼主bcbnewbie()2005-11-02 15:57:38 在 C++ Builder / 网络及通讯开发 提问

以前没有接触过网络通讯,现在准备写一个即时通讯的工具,要实现如下功能:  
  1.同时在线1000人左右聊天  
  2.音频、视频聊天  
  3.文件传输  
  4.简单的对战游戏  
  5.可以群聊,也可以点对点的聊天  
   
          现在的问题是用BCB戴的TSocketServer和TSocketClient能不能实现上述功能,性能如何。因为我搜索了以前的帖子好像用两个控件不如直接用Socket   API那样好。我对Socket   API几乎没有了解,请推荐一本Socket   API编程的书。 问题点数:50、回复次数:29Top

1 楼ccrun(老妖)(www.ccrun.com)回复于 2005-11-02 16:01:52 得分 0

大工程啊老弟。Top

2 楼FengSC(小猪快跑)回复于 2005-11-02 16:47:22 得分 0

如果你对socket   api都没有了解,那么这样的系统,够你研究个3~5年了Top

3 楼bcbnewbie()回复于 2005-11-02 17:59:58 得分 0

3~5年太夸张了吧,基本的TSocketServer、TSocketClient还是会用的,就是怕性能上不去。Top

4 楼zwq_2002(抗战时期)回复于 2005-11-02 18:57:40 得分 0

socket上面没什么复杂内容,主要是性能的优化,要涉及到服务器设计模型Top

5 楼niiv(一叶)回复于 2005-11-03 16:06:50 得分 0

只要带宽足够,TSocketServer、TSocketClient一点问题都没有。  
  不明白为什么经常有人说TSocketServer、TSocketClient性能不好,用了好多年,感觉效率很高,也很稳定。  
   
  很好奇,如果1000人都在大厅里公开发言,会是怎么样的一个情境。屏幕应该滚得很快吧?QQ好象一个聊天室最多也就允许180个用户吧?Top

6 楼pp616(坏蛋)回复于 2005-11-03 19:28:11 得分 0

《windows网络编程》人邮的   去看吧。   对你会非常有帮助。Top

7 楼godoli(snoogod)回复于 2005-11-04 15:38:46 得分 0

《Windows网络编程技术》比较好。   BCB中使用的是Winsock   1.1版本。TSocketServer、TSocketClient中的非阻塞主要是通过select、WSAAsyncSelect、重叠I/O机制方法。处理SOCKET不是太多的情况是能够胜任的。向楼主说的1000多个,就应该考虑使用完成端口模型,这是BCB中的控件无法完成的,必须要使用Winsock   2.2版本,这个版本中的对重叠I/O进行了自身的优化,不想BCB中使用的是WriteFile、ReadFile...        
  Top

8 楼pp616(坏蛋)回复于 2005-11-06 18:27:02 得分 0

楼上的你说的不对。  
   
  1.“TSocketServer、TSocketClient中的非阻塞主要是通过select、WSAAsyncSelect、重叠I/O机制方法。”  
  那2个控件非阻塞时用的就是WSAAsyncSelect模式   不存在select   和   重叠I/O   请你仔细阅读   scktcomp.pas  
   
  2.控件中WriteFile、ReadFile   的使用是在阻塞模式中使用的,在非阻塞中并未使用。  
   
  3.WriteFile、ReadFile   本身就可以用重叠I/O来做。  
   
  如果我说的不对请更正。  
  Top

9 楼DelphiGuy()回复于 2005-11-06 22:25:36 得分 0

就算你使用了线程池+重叠I/O+完成端口,  
  效率也不会比使用VCL   Socket组件(自带的或者Indy)高超过5%。  
  不信你就试试。  
  我就用Indy处理过同时超过2000个TCP连接,  
  完全没有问题。  
  Top

10 楼songhtao(三十年孤独)回复于 2005-11-07 08:24:13 得分 0

Indy   很稳定,效率很好,而且跨平台。Top

11 楼wyb_45(小兵)回复于 2005-11-07 09:04:23 得分 0

socket   api比较简单   也跨平台  
  就是要自己处理   多线程  
                    WORD   wVersionRequested;  
                    WSADATA   wsaData;  
                    Sleep(100);  
                    wVersionRequested=MAKEWORD(2,0);  
                    int   err=WSAStartup(wVersionRequested,&wsaData);  
  。。。  
  int   Connect_Server(AnsiString   host,   u_short   port)  
  {  
  int   i,   s;  
  long*   p;  
  hostent*   phe;  
  sockaddr_in   sin;  
  DWORD   Address;  
  sin.sin_family   =   AF_INET;  
  sin.sin_port   =   htons(port);  
   
  Address   =   inet_addr(host.c_str());  
  if   (Address   ==   INADDR_NONE)   {  
  phe   =   gethostbyname(host.c_str());  
  if   (phe)   {  
  p   =   (long*)(*phe->h_addr_list);  
  sin.sin_addr.s_addr   =   *p;  
  }  
  }  
  else   {  
  i   =   inet_addr(host.c_str());  
  if   (i!=-1)  
  sin.sin_addr.s_addr   =   i;  
  }  
   
  s   =   socket(PF_INET,SOCK_STREAM,0);  
  if   (s   ==   INVALID_SOCKET)  
  return   0;  
  if   (connect(s,(struct   sockaddr   FAR   *)&sin,sizeof(sin))<0)               //   ==   SOCKET_ERROR)   {  
                  {  
                  closesocket(s);  
                  return(-1);        
  //int   i   =   WSAGetLastError();  
  // return   0;  
  }  
  else  
  return   s;  
  }  
   
  BOOL   RecvStream(SOCKET   s,   TMemoryStream*   Stream)  
  {  
  char   buf[PACKAGESIZE];  
  //int   namelen;  
                  int   pktlen;  
  int   i   =   1;  
  for   (;;i++)   {  
  Application->ProcessMessages();  
  if   ((pktlen   =   recv(s,buf,sizeof(buf),0))<0)   {  
  //接收数据失败  
  return   false;  
  }  
  else   if   (pktlen   ==   0)  
  break;  
  else   {  
  Stream->Seek(0,soFromEnd);  
  Stream->Write(buf,pktlen);  
  }  
  }  
  Stream->Seek(0,soFromBeginning);  
  closesocket(s);  
  return   true;  
  }  
   
   
  if((pktlen   =send(sockfd,buf,send_len,0))<=0)  
                    {  
                      。。。  
                                  break;  
                    }  
  Top

12 楼bcbnewbie()回复于 2005-11-07 09:40:38 得分 0

谢谢大家回帖,我的想法就是服务器指转发更行IP的管理,然后客户端采用点对点直接联系。定义一些通讯命令字。还有一点疑问采用阻塞加线程的方式如果同时有几百个连接请求,服务器不是要同时开几百个线程对应,那不是对服务器的要求很高,,如果是非阻塞的方式,假设一个客户连接的请求处理很长时间,那么其他用户是不是可能会得不到服务?Top

13 楼constantine(飘遥的安吉儿)回复于 2005-11-07 12:37:27 得分 0

indy   很好我到不见的,还是有些不见人意,版本变化比较大,对于升级不好  
  如果你用TSocketServer和TSocketClient,那么是无法实现p2p的,p2p只能用udp  
  不过如果要简单用server转发很简单,不过这样会增加server的负担  
  另外你说的情况不会出现,既然是多线程,那么每个client的线程都是独立的,“那么其他用户是不是可能会得不到服务”这个不用担心  
  如果真要做到你提的要求,你可以考虑用indy的idudpserver控件来做Top

14 楼wangxiangsjz(王翔)回复于 2005-11-07 16:21:12 得分 0

http://www.loveunix.net/bbs/index.php?showtopic=22093Top

15 楼niiv(一叶)回复于 2005-11-08 11:34:33 得分 0

和   constantine(飘遥的安吉儿)   有类似感觉,Indy也不见得很好。  
   
  1000个客户端同时连接服务器时,TSocketServer可以3秒左右完成所有连接,如果每客户端通过服务器转发数据,每秒1K   Bytes,服务器占用的资源几乎为0%。  
   
  注:测试PC,CPU=赛扬1G,内存=256M,出入口带宽最高达1MBytes/s。  
   
  UDP方面用Indy的好些Top

16 楼BCB2006(i like bcb)回复于 2005-11-08 13:47:36 得分 0

楼上的你是如何测试1000个并发连接的?如果是传送文件或语音视频呢?  
  这么说TSocketServer很强啊Top

17 楼niiv(一叶)回复于 2005-11-08 16:16:39 得分 0

测试结构如下:  
  服务器处于公网(电信级机房托管服务器),  
  服务器配置:CPU=赛扬1G,内存=256M,出入口带宽最高达1MBytes/s。  
  使用BCB的TSocketServer  
   
  客户端使用BCB的TSocketClient,生成1000个实例后,使用循环连接该服务器的同一端口(也就是相同IP的相同端口).  
   
  服务器端记录第1个连接到第1000个连接(OnAccept事件)的时间差。  
  最短时间3秒以下,一般在10秒左右。  
   
  个人用TSocketServer和TSocketClient有4年了,无论从效率和稳定性上都非常好,但也经常看到论坛上有人说丢包之类的问题,我没碰到过,估计是程序有问题。  
   
  To:   BCB2006(i   like   bcb)    
  TSocketServer,无法区分你的数据是否为“文件或语音视频”,只视乎数据传送量。Top

18 楼bcbnewbie()回复于 2005-11-08 16:44:58 得分 0

谢谢大家回复!  
  想请教   niiv(一叶)   对于多人聊天的方案,就性能方面有什么看法。  
  比如说方案一由服务器转发用户的所有的数据包,服务器采用阻塞+多线程   或者非阻塞方式  
  第二种服务器转发登录用户的好友的IP,让登录用户和他的好友直接p2p的方式联系,在客户端用多线程+自己定义的消息格式。  
  那个更好一点,或则有更好的方案?Top

19 楼niiv(一叶)回复于 2005-11-09 15:57:04 得分 0

请留email/QQ/msn。Top

20 楼alloutoflove(andrew)回复于 2005-11-09 16:02:49 得分 0

偶是进来学习的.Top

21 楼bcbnewbie()回复于 2005-11-09 17:26:26 得分 0

qq:124271328]  
  bcbnewbie@21cn.com  
  谢谢!Top

22 楼constantine(飘遥的安吉儿)回复于 2005-11-09 17:35:52 得分 0

第二种好多了,现在的即时通基本上都是这样,但是不通的时候会让server转发Top

23 楼linuxghs()回复于 2005-11-09 20:27:09 得分 0

我也是用bcb开发的即时通讯软件,用的udp,现在效果很好  
  我用的也是第二种方法。除非是离线消息才要在server存储。Top

24 楼bcbnewbie()回复于 2005-11-09 20:30:13 得分 0

老兄,能留个QQ号交流一下吗?Top

25 楼Yans(跟贴是一种友谊)回复于 2005-11-14 14:14:17 得分 0

学习Top

26 楼dxkh(沧海一粟)回复于 2005-11-14 16:07:27 得分 0

确实是个大工程。。。Top

27 楼happyct(绿叶对大树的情怀)回复于 2005-11-14 16:29:55 得分 0

我做这个项目也做了3个月了。用的是delphi开发  
  用的TindyUdpServer,目的是P2P  
   
  目前已经具有的功能:  
  1. 文件收发:支持文件托放操作,收发过程中的信息交互(如取消、中止、错误),支持一对多发送  
  2. 信息收发:包括文字、手写信息、屏幕拷贝、表情图片(可自行添加),声音信息(即录音),这些信息可以混合编辑  
  3. 魔法表情:除系统提供的之外,用户可自由的自行添加  
  4. 屏幕震动  
  5. 输入状态提示功能,对方开始及结束输入都可以及时看到  
  6. 来信提示:托盘图标闪动、主窗体上方提示闪动、弹出提示窗口,任务栏闪动等  
  7. 头像设定及编辑:用户可自定义头像,系统提供了一个简单方便的编辑工具,可直接对头像进行设定编辑  
  8. 在线状态设定及个人文字说明  
  9. 历史消息查询功能(正在修改)  
  10. 临时群组(多方会谈):包括创建、添加、修改及删除。非组创建者只能添加用户,不能删除  
  11. 系统皮肤整体变色  
  12. 用户自定义链接。类似于收藏夹  
   
  插件接口:  
  消息收发接口  
  文件收发接口(其实就是一个插件)  
   
  上述功能已经完成,同时对50个在线用户的群聊没什么问题  
  同时对30个用户收发文件没什么问题  
  视频语音还没做Top

28 楼happyct(绿叶对大树的情怀)回复于 2005-11-14 16:34:20 得分 0

总结:  
   
  1、对于某某控件好,某某控件不好这样的评论,一般来说,都是不客观的。那是开发者自己水平问题(当然我的水平也不行)  
   
  2、要P2P,请用UDP,TCP没办法实现的,除非限于局域网或都是公网  
   
  3、请做好详尽的系统分析,工程约大,这项工作越重要。这个项目的的系统分析时间是1个月,除系统分析文档外,其他文档还没写  
   
  4、自我感觉速度还比较快,中间遇到过2次问题,都是安吉儿帮忙解决的,在此谢过Top

29 楼happyct(绿叶对大树的情怀)回复于 2005-11-14 16:37:23 得分 0

其中还做了几个不大不小的控件。有点模仿QQ和MSN的感觉。自我感觉不错。如果有需要的,可以向我索取,可惜不能贴图。Top

相关问题

  • 用VC++6.0写局域网即时通讯工具?
  • 求VC++写的即时通讯程序源码
  • 请教局域网即时通讯工具哪个好一些?类似QQ的
  • 想写一个即时通讯的小软件用Tcp还是Udp?
  • 请问怎么实现即时通讯?
  • 即时通讯程序原理?
  • 怎么实现asp.net的即时通讯?
  • 关于即时通讯与UDP、P2P
  • 即时通讯系统(求源码)
  • P2P与即时通讯系统建设

关键词

  • 控件
  • bcb
  • 性能
  • 聊天
  • socket
  • 版本
  • api
  • tsocketserver
  • tsocketclient
  • pktlen

得分解答快速导航

  • 帖主:bcbnewbie

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

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