300大洋求解QQ通信原理!(在线等,解决后马上结贴给分!) (300分)

  • 主题发起人 主题发起人 mynlxx
  • 开始时间 开始时间
OICQ使用UDP。
简化的流程:
1。用户启动客户端程序,客户端程序首先用本地数据校验密码,如通过,则转到3;
2。如本地校验失败,则询问用户是否要求交给服务器验证;
3。客户端程序向服务器端口8000发出登陆数据包,其中包括qq号、密码等信息;
4。服务器校验密码后向客户端的4000(也可能是其他端口,要视具体的bind情况而定)端口回送响应数据包,并发送好友列表(客户端在本地机器上也存有一份好友列表),其中包括在线好友的名单与IP、端口号;
5。与好友通话时,客户端程序首先试图向该好友的ip直接发送数据,若发送失败(例如网络状态不好、防火墙或好友不在线),则交给服务器转发(转发有可能造成丢包);
6。好友收到信息后,回送一个确认信号给发送端,结束一次通话。
注:由于UDP协议不是一个“可靠”协议,故意上的发送、响应的交互过程有可能不是一次完成的,会出现多次发送、多次响应的情况,但有效发送、响应只有一次。
客户端程序会不断地(间隔只有几秒钟)向服务器发出确认信息包,以确认当前的网络连接有效;服务器收到信息包后,更新好友列表并回送客户端,实现好友上线、下线通知。
客户端和客户端通讯采用UDP,客户端程序和服务器端也是UDP
上面步骤3是轮流向tencent的若干个服务器轮流发请求,这大概是他们的负载平衡的办法。
步骤4在服务器端纪录登陆客户的ip/port,这可能是经过了proxy的映射IP/Port,因此其他的client只要得到这个映射,就可以直接发到目的地。
也就是说,步骤5中的IP和Port未必是好友真正的ip和端口。因此,如果对方的端口不是4000/400x,八成它是在代理服务气后。
只有UDP协议才有这种奇怪的映射特性,所以可以做到代理服务器后的CLIENT也可接受其他人发来的消息。
但UDP协议是不稳定的,需要加时间戳、校验码等。而且长度一般在512字节内
 
我的想法和测试方法跟不困是一样的。
也认为是这种方法,不可能客户端的数据都通过服务器转发。
就算服务器能转发得到,为什么另局域网能上网,为什么又会发送不到呢?
所以我坚信UDP可以做到不同局域网内通信。

但问题出在,我用一台有公网IP的机器做服务器,记录局域网内发过来的:FromIP,PORT
(TNMUDP 中Datareceveid里取的),数据,但转给另一局域网内机器,照样往这发却收不到。
且,这台公网IP中再创建另一个TNMUDP控件,往这发都收不到,只能是接收过该局域网内那
台机器消息的那个UDP发送,它才认,所以怪了。

 

你遇到的问题可能是由于网关动态分配给的端口改变引起的,
我在寻找一台测试主机。。
 
TO 不困:非常感谢,可惜我家里的机器没开,否则可以用来测试用。
QQ:14690274 我还有别人的主机,我可以拿来测试,如果需要,可以马上联系我。
 
我之前一直使用TNMUDP得,但屡次遇到莫名其妙的Stream Write Error错误之后决定改用ICS,
但ICS仿佛不支持同一个端口的监听和发送,这样的话如果客户端处在局域网内,
服务器端就无法得到确切的客户端接受端口,因为局域网内客户端向网关请求的端口是发送端口,
这该如何解决?

mynlxx:我也在制作同类软件,希望能够互相交流。
MSN:xonton@hotmail.com
QQ:10189009


 
晕,你比我快阿。。
 
可否给小第一份看看cxwoyaoying@etang.com
 
最新测试:
我用VC编了一个UDP测试小程序,也是出现同样的问题。所以我认为不关系到控件的问题
,但QQ居然能实现,我实在想不通他用了什么方法?
 
QQ有的时候是通过服务器中转的消息,而服务器和CLIENT之间一直是保持联系的
 
但是大部分的QQ消息都是通过不同局域网直接传送的啊?
 
这个要看代理的NAT表的类型,这个问题CSDN上讨论的比较详细,你可以上去找找哪个帖子
 
不管代理NAT表是什么类型,我都要能实现,就象QQ一样,他只要你选择
上网类型就可以了。张无忌你有办法吗?
 
http://gujie.zhibo.net
 
看看DELPHI 6中自身带的例子,好象是在DELPHI6/DEMO/FAST目录下.
 
实际上QQ也没有完全做到真正的点对点!如果两个点处在两个不同的网络内时,它的信息就是通过服务器中转的,当有一方用的公网IP时,服务器协调另一方直接连接此IP和端口(仅仅是我的推测而已,我没办法获得QQ的原代码,QQ好象不是用delphi做的~~)
 
这样好像可以的,当服务器C取得A机(内网)IP和端口后,发给C机(内网),C机发送信息给A机时,要将自已的IP改变,就相当于IP欺骗,因为A机在接收信息时会验证发送方的IP,这样经过伪装的信息就可以通过了。不知道对不,我也正在研究。E_MAIL:hfqxfx@163.com
 
各位大哥大姐:我现在也在考虑互连网聊天程序,不过还没什么进展,
希望大家共同研究!!
 
ip+port应该就可以定位服务了吧?管你是不是主机呢。你们没看到在局域网里上网的机器的端口号都怪怪的,如果一台主机上开两个qq,端口号就是4000和4001了。不过我认为客户端是必须得从服务器读取好友的ip+port。
 
我可以给一个想法你,就是仿照,网页式的聊天室的原理来做。
只要注意一点就行了:
不是服务器向客户机发信息,而是客户机向服务器“取”信息。

 
liaoliao说的有点象webservice的功能。这个问题以前讨论的很多,除了qq我还见过几个有这种功能的软件,比如王志东的gkstar。当大家把问题延伸到http代理协议和sock5代理协议上时,便停止不前了。没有听说过靠个人水平使用delphi能够达到这一步的人,尤其是delphi的程序执行效率比c写的程序要低很多,如果要写这类程序,低层用c好,否则delphi本身就给这种对服务器要求很高的程序制造了很多麻烦,另外c,c#中有许多面向对象编程工具所不具有的功能。记得我去年从网上搜索peer—to— peer的文章时,只有一篇c#的文章可以参考。当然如果楼上仅仅是要求实现功能,用delphi也可以实现。只不过一旦可以做到这一点的,都会把它作为商业秘密,不会轻易透露的。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部