探讨QQ的点对点通信原理 QQ除了能在局域网中通信外,它还能在INTERNET中通信,除了用服务器来中转消息外,它还有什么别的方式吗,是否可以直接点对点地不通过服务器来中转消息?另外,有没有这方面的源代码来提供学习? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我闲着没事.用防火墙跟QQ开了个玩笑.我发现QQ的登录过程是这样的:1.先用UDP 6000端口连接 服务器 8000 端口.如果不成功!2.改用UDP 6001 端口连接 服务器 8000 端口. 如果不成功!3.改用UDP 6000端口再试一次.如果不成功!4.改用TCP连接服务器 80 端口.如果不成功!5.改用TCP连接服务器 443 端口.如果不成功!6.登录失败!而MSN则简单得多1.用TCP连接 服务器80 端口. 如果不成功!2.用TCP连接 服务器443 端口.如果不成功!3.登录失败! 我认为QQ只是从服务器得到在线好友的IP然后直接和好友通信的,如果什么都先到服务器再到好友服务器负担肯定很重。 先和服务器连接,然后获得ip列表,然后用ip点对点通信。每次客户改变状态,广播。 我认为QQ只是从服务器得到在线好友的IP然后直接和好友通信的,如果什么都先到服务器再到好友服务器负担肯定很重。先和服务器连接,然后获得ip列表,然后用ip点对点通信我觉得大家说的都很对,先和服务器连接,获得IP后再点对点通信,我在VCCODE下载了一个MYICQ程序,也是模仿QQ的一个程序,不过现在还没有运行成功。很想了解一下点对点通信的原理,欢迎大家一起研究探讨 为什么QQ的信息能进入局域网内部的机子? 主要解答者: pajun 提交人: prettywolf 感谢: chenjiming、hequhecong、pajun、ququshb、icansaymyabc、csdnfriend、csdnfriend、smartlu、uaiia、drip、icelight、table、Sc0rp10、ndy_w、Sc0rp10、ndy_w、Sc0rp10、cuterain、cnxmouse、wil、cangus、joe0、m_pDelphi、philis 审核者: masterz 论坛对应贴子: 查看 A : 听说是用了UDP协议,但是我写了一段程序: void CSendDlg::OnSend() { int i=0; UpdateData(TRUE); BYTE code1,code2,code3,code4; char ip[16]; m_ipaddr.GetAddress(code1,code2,code3,code4); sprintf(ip,"%d.%d.%d.%d",code1,code2,code3,code4); int length=m_message.GetLength(); if(length){ char message[256]; for (int j=0;j<256;j++) *(message+j)=0; for(i=0;i<m_message.GetLength();i++) *(message+i)=m_message.GetAt(i); Cmysock m_mysock; m_mysock.Create(10880,SOCK_DGRAM); m_mysock.SendTo(message,sizeof(message),12180,ip); m_mysock.Close(); m_message=""; UpdateData(FALSE); } else MessageBox("不能发空信息"); m_msg.SetFocus(); } 我叫人在另一个局域网内的一台机子上运行了接收端,结果什么反应也没有。 怎么回事呀,有人做过这方面的例子吗? 经测试过,在同一个局域网内能正常接收。 --------------------------------------------------------------- 如果AB都在防火墙里面,A连接QQ服务器的时候,服务器就知道A的网关的IP和A经过网关时被转换的端口。B访问QQ服务器就知道了它,然后就直接对A网关IP和A被转换后的端口,A的网关收到后就会自动发给A机器了 其实就是NAT的功能 --------------------------------------------------------------- 这个东西在一个网站有详细的说明:http://www.jabber.org/jeps/ --------------------------------------------------------------- 其实,这个问题很简单。虽然QQ客户端在局域网内,但是当你打开QQ登录到QQ服务器时,通过防火墙,你的客户端与QQ服务器建立了一个长连接。你可以用netstat -a 看到此连接的状态是 establish。 此时,在QQ服务器那面看到的连接的IP是你们局域网防火墙的对外IP。举个例子: QQ服务器 IP:202.96.170.175 服务端口:3333 你的机器在局域网中内部IP: 192.168.0.10 你局域网出口防火墙InternetIP: 202.106.10.100 你的客户端的请求将通过防火墙出去,如果防火墙没有禁止访问Internet上3333端口服务,那么你的QQ客户端可以正常工作。你看到的连接是 (netstat -a) 192.168.0.10:4817 202.96.170.175:3333 establish 这是一个假象。通过QQ服务器看到的连接是: 202.96.170.175:3333 202.106.10.100:31234 establish 这样,防火墙上的31234口对应的就是你机器的4817口。(由于你是发起方,这个数是变化的。动态的) 当有信息给你时,QQ服务器只需要发给防火墙的31234口即可。(这里防火墙作了地址翻译) 所以,你要测试两个局域网的互传时,除非你可以将服务端的IP和端口通过你本地网可以静态访问到,否则无法成功! --------------------------------------------------------------- 其实是一个很简单的问题只要按着接受到的ip和端口发回去就可一了 2 pajun(臭棋篓子): 你是在讲 tcp吧,这里是说的udp 哦 另外有个问题。 在代理服务器上,会有一个port分配给local 机子的一个udp,它会保留多久,要是我1个小时不发udp数据数据,这个port还有用吗?还能出外面发到local 网吗?要是2小时,10小时呢? --------------------------------------------------------------- 其实只要按着接受到的ip和端口发回去即可 所以,你不可能直接就把消息发到局域网内的机器。 你还是要先通过公网上固定的服务器获知局域网内的机器的连接方法。 --------------------------------------------------------------- 通过有个IP多播的东西 ICMP的很好可以实现,可以跨网段通信,可是很少的路由器支持! 这两个QQ初始连接肯定要服务器来建立,然后服务器把双方的网关地址和端口告诉双方,是否可以解决呢? --------------------------------------------------------------- 这样好像有点客户端窃取服务器的连接的意思,虽然是服务器自愿的:) 虽然网关不会往这个窃取服务器连接的客户端发消息,但是你可以往对方和服务器建立的连接得端口上发消息!! REF: 这样,防火墙上的31234口对应的就是你机器的4817口。(由于你是发起方,这个数是变化的。动态的) 当有信息给你时,QQ服务器只需要发给防火墙的31234口即可。(这里防火墙作了地址翻译) END 这个有意思,你要发消息,只要往对方防火墙和服务器建立的连接上发消息就可以了?但是防火墙建立的连接是和服务器的,如果服务器一直不响应这个连接,这个连接会维持多久? --------------------------------------------------------------- qq是不断的给server发udp包用来保持本机和nat的端口映射, 用一个听包的程序可以看到, 所以server知道每个连上qq用户的准确地ip,port或者是nat的ip和映射的port 另外实现两个不同子网的tcp连接是不可能的,因为一个syn是不可能到达的 不过可以在udp层次上实现vpn来模拟tcp, qq的会员之所以能实现不同子网的语音聊天就是这样, 还有一种方法就是直接在nat上面作一个固定的地址转换, 不过这样只能用于固定的用户 --------------------------------------------------------------- 给你们晕死!!!!!!! UDP协议是很容易在网间通讯的! 给你一个方案 SERVER:用一个端口接收客户的上线信息! 简单的例子: void ???::OnReceive(int nErrorCode) { struct { DWORD CMD; DWORD UserID; ..... }Data; ReceiveFrom(&Data,sizeof(Data),m_ip,m_port); switch(Data.CMD){ case 登陆: UserLogin(Data.UserID,UserIP,UserPort);//将用户登陆端口地址加入数据库 break; case 查询: SendUserPort(Data.UserID,UserIP,UserPort);//返回指定用户登陆端口地址 break; } CLIENT:向服务器发出读取特定用户端口的请求,得到后用该端口与其通讯 这个方法可以让 Client<==>Client 在任何代理间运行! --------------------------------------------------------------- 这两天看到,两个关于Intnet访问局域网内部机器贴子,于是乎,说一说我的观点,请指教。局域网中的IP在内部虽然可以指定。但是每次开机映射到外部时都是动态分配的。也就是任意两次开机你会有不同的IP.这种分配通过代理服务器映射。至于QQ向内部的机器发送信息是因为,每次登录时你机器会向QQ服务器申报此次你的机器IP地址。 --------------------------------------------------------------- 顺便贴篇PPP协议的介绍 PPP协议简介 -------------------------------------------------------------------------------- 发表日期:2003年2月25日 出处:北京科技大学(管庄校区) 作者:曾芙蓉 已经有168位读者读过此文 一、介绍 PPP(Point-to-Point Protocol点到点协议)是为在同等单元之间传输数据包这样的简单链路设计的链路层协议。这种链路提供全双工操作,并按照顺序传递数据包。设计目的主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案。 二、 PPP链路建立过程 PPP协议中提供了一整套方案来解决链路建立、维护、拆除、上层协议协商、认证等问题。PPP协议包含这样几个部分:链路控制协议LCP(Link Control Protocol);网络控制协议NCP(Network Control Protocol);认证协议,最常用的包括口令验证协议PAP(Password Authentication Protocol)和挑战握手验证协议CHAP(Challenge-Handshake Authentication Protocol)。 LCP负责创建,维护或终止一次物理连接。NCP是一族协议,负责解决物理连接上运行什么网络协议,以及解决上层网络协议发生的问题。 下面介绍PPP链路建立的过程: PPP链路状态机如图1所示。一个典型的链路建立过程分为三个阶段:创建阶段、认证阶段和网络协商阶段。 阶段1:创建PPP链路 LCP负责创建链路。在这个阶段,将对基本的通讯方式进行选择。链路两端设备通过LCP向对方发送配置信息报文(Configure Packets)。一旦一个配置成功信息包(Configure-Ack packet)被发送且被接收,就完成了交换,进入了LCP开启状态。 应当注意,在链路创建阶段,只是对验证协议进行选择,用户验证将在第2阶段实现。 阶段2:用户验证 在这个阶段,客户端会将自己的身份发送给远端的接入服务器。该阶段使用一种安全验证方式避免第三方窃取数据或冒充远程客户接管与客户端的连接。在认证完成之前,禁止从认证阶段前进到网络层协议阶段。如果认证失败,认证者应该跃迁到链路终止阶段。 在这一阶段里,只有链路控制协议、认证协议,和链路质量监视协议的packets是被允许的。在该阶段里接收到的其他的packets必须被静静的丢弃。 最常用的认证协议有口令验证协议(PAP)和挑战握手验证协议(CHAP)。 认证方式介绍在第三部分中介绍。 阶段3:调用网络层协议 认证阶段完成之后,PPP将调用在链路创建阶段(阶段1)选定的各种网络控制协议(NCP)。选定的NCP解决PPP链路之上的高层协议问题,例如,在该阶段IP控制协议(IPCP)可以向拨入用户分配动态地址。 这样,经过三个阶段以后,一条完整的PPP链路就建立起来了。 三、 认证方式 1)口令验证协议(PAP) PAP是一种简单的明文验证方式。NAS(网络接入服务器,Network Access Server)要求用户提供用户名和口令,PAP以明文方式返回用户信息。很明显,这种验证方式的安全性较差,第三方可以很容易的获取被传送的用户名和口令,并利用这些信息与NAS建立连接获取NAS提供的所有资源。所以,一旦用户密码被第三方窃取,PAP无法提供避免 在同一个局域网内的两台机子上QQ又是怎么通信的,通过服务器?还是不通过服务器直接通信?它和BT的点对点通信原理又有什么不同? 关于INTERNET组播? 有两个问题请教 如何不等图片文件接受完就显示部分图片 怎样动态调整.rc中定义的控件的位置和大小? ListCtrl视图中的数据怎么重新写入数据库呢,请教,在线等待!! 怎样通过ProcessID获得Process的Handle 关于文件读写的疑问! 求:图象算法(物体追踪) 位图问题 询问wyzegg MFC 中画圆的函数? 我想知道这样的代码使用什么写的?
2.改用UDP 6001 端口连接 服务器 8000 端口. 如果不成功!
3.改用UDP 6000端口再试一次.如果不成功!
4.改用TCP连接服务器 80 端口.如果不成功!
5.改用TCP连接服务器 443 端口.如果不成功!
6.登录失败!而MSN则简单得多1.用TCP连接 服务器80 端口. 如果不成功!
2.用TCP连接 服务器443 端口.如果不成功!
3.登录失败!
主要解答者: pajun 提交人: prettywolf
感谢: chenjiming、hequhecong、pajun、ququshb、icansaymyabc、csdnfriend、csdnfriend、smartlu、uaiia、drip、icelight、table、Sc0rp10、ndy_w、Sc0rp10、ndy_w、Sc0rp10、cuterain、cnxmouse、wil、cangus、joe0、m_pDelphi、philis
审核者: masterz 论坛对应贴子: 查看
A : 听说是用了UDP协议,但是我写了一段程序:
void CSendDlg::OnSend()
{
int i=0;
UpdateData(TRUE);
BYTE code1,code2,code3,code4;
char ip[16];
m_ipaddr.GetAddress(code1,code2,code3,code4);
sprintf(ip,"%d.%d.%d.%d",code1,code2,code3,code4);
int length=m_message.GetLength();
if(length){
char message[256];
for (int j=0;j<256;j++)
*(message+j)=0;
for(i=0;i<m_message.GetLength();i++)
*(message+i)=m_message.GetAt(i);
Cmysock m_mysock;
m_mysock.Create(10880,SOCK_DGRAM);
m_mysock.SendTo(message,sizeof(message),12180,ip);
m_mysock.Close();
m_message="";
UpdateData(FALSE);
}
else MessageBox("不能发空信息");
m_msg.SetFocus();
}
我叫人在另一个局域网内的一台机子上运行了接收端,结果什么反应也没有。
怎么回事呀,有人做过这方面的例子吗?
经测试过,在同一个局域网内能正常接收。
---------------------------------------------------------------
如果AB都在防火墙里面,A连接QQ服务器的时候,服务器就知道A的网关的IP和A经过网关时被转换的端口。B访问QQ服务器就知道了它,然后就直接对A网关IP和A被转换后的端口,A的网关收到后就会自动发给A机器了
其实就是NAT的功能
---------------------------------------------------------------
这个东西在一个网站有详细的说明:http://www.jabber.org/jeps/
---------------------------------------------------------------
其实,这个问题很简单。虽然QQ客户端在局域网内,但是当你打开QQ登录到QQ服务器时,通过防火墙,你的客户端与QQ服务器建立了一个长连接。你可以用netstat -a 看到此连接的状态是 establish。
此时,在QQ服务器那面看到的连接的IP是你们局域网防火墙的对外IP。举个例子:
QQ服务器 IP:202.96.170.175 服务端口:3333
你的机器在局域网中内部IP: 192.168.0.10
你局域网出口防火墙InternetIP: 202.106.10.100
你的客户端的请求将通过防火墙出去,如果防火墙没有禁止访问Internet上3333端口服务,那么你的QQ客户端可以正常工作。你看到的连接是 (netstat -a)
192.168.0.10:4817 202.96.170.175:3333 establish
这是一个假象。通过QQ服务器看到的连接是:
202.96.170.175:3333 202.106.10.100:31234 establish
这样,防火墙上的31234口对应的就是你机器的4817口。(由于你是发起方,这个数是变化的。动态的)
当有信息给你时,QQ服务器只需要发给防火墙的31234口即可。(这里防火墙作了地址翻译)
所以,你要测试两个局域网的互传时,除非你可以将服务端的IP和端口通过你本地网可以静态访问到,否则无法成功!
---------------------------------------------------------------
其实是一个很简单的问题只要按着接受到的ip和端口发回去就可一了
2 pajun(臭棋篓子): 你是在讲 tcp吧,这里是说的udp 哦
另外有个问题。
在代理服务器上,会有一个port分配给local 机子的一个udp,它会保留多久,要是我1个小时不发udp数据数据,这个port还有用吗?还能出外面发到local 网吗?要是2小时,10小时呢?
---------------------------------------------------------------
其实只要按着接受到的ip和端口发回去即可
所以,你不可能直接就把消息发到局域网内的机器。
你还是要先通过公网上固定的服务器获知局域网内的机器的连接方法。
---------------------------------------------------------------
通过有个IP多播的东西 ICMP的很好可以实现,可以跨网段通信,可是很少的路由器支持!
这两个QQ初始连接肯定要服务器来建立,然后服务器把双方的网关地址和端口告诉双方,是否可以解决呢?
---------------------------------------------------------------
这样好像有点客户端窃取服务器的连接的意思,虽然是服务器自愿的:)
虽然网关不会往这个窃取服务器连接的客户端发消息,但是你可以往对方和服务器建立的连接得端口上发消息!!
REF:
这样,防火墙上的31234口对应的就是你机器的4817口。(由于你是发起方,这个数是变化的。动态的)
当有信息给你时,QQ服务器只需要发给防火墙的31234口即可。(这里防火墙作了地址翻译)
END
这个有意思,你要发消息,只要往对方防火墙和服务器建立的连接上发消息就可以了?但是防火墙建立的连接是和服务器的,如果服务器一直不响应这个连接,这个连接会维持多久?
---------------------------------------------------------------
qq是不断的给server发udp包用来保持本机和nat的端口映射,
用一个听包的程序可以看到,
所以server知道每个连上qq用户的准确地ip,port或者是nat的ip和映射的port
另外实现两个不同子网的tcp连接是不可能的,因为一个syn是不可能到达的
不过可以在udp层次上实现vpn来模拟tcp,
qq的会员之所以能实现不同子网的语音聊天就是这样,
还有一种方法就是直接在nat上面作一个固定的地址转换,
不过这样只能用于固定的用户
---------------------------------------------------------------
UDP协议是很容易在网间通讯的!
给你一个方案
SERVER:用一个端口接收客户的上线信息!
简单的例子:
void ???::OnReceive(int nErrorCode)
{
struct {
DWORD CMD;
DWORD UserID;
.....
}Data;
ReceiveFrom(&Data,sizeof(Data),m_ip,m_port);
switch(Data.CMD){
case 登陆:
UserLogin(Data.UserID,UserIP,UserPort);//将用户登陆端口地址加入数据库
break;
case 查询:
SendUserPort(Data.UserID,UserIP,UserPort);//返回指定用户登陆端口地址
break;
}
CLIENT:向服务器发出读取特定用户端口的请求,得到后用该端口与其通讯
这个方法可以让 Client<==>Client 在任何代理间运行!
---------------------------------------------------------------
这两天看到,两个关于Intnet访问局域网内部机器贴子,于是乎,说一说我的观点,请指教。局域网中的IP在内部虽然可以指定。但是每次开机映射到外部时都是动态分配的。也就是任意两次开机你会有不同的IP.这种分配通过代理服务器映射。至于QQ向内部的机器发送信息是因为,每次登录时你机器会向QQ服务器申报此次你的机器IP地址。
---------------------------------------------------------------
顺便贴篇PPP协议的介绍
PPP协议简介
--------------------------------------------------------------------------------
发表日期:2003年2月25日 出处:北京科技大学(管庄校区) 作者:曾芙蓉 已经有168位读者读过此文
一、介绍
PPP(Point-to-Point Protocol点到点协议)是为在同等单元之间传输数据包这样的简单链路设计的链路层协议。这种链路提供全双工操作,并按照顺序传递数据包。设计目的主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案。
二、 PPP链路建立过程
PPP协议中提供了一整套方案来解决链路建立、维护、拆除、上层协议协商、认证等问题。PPP协议包含这样几个部分:链路控制协议LCP(Link Control Protocol);网络控制协议NCP(Network Control Protocol);认证协议,最常用的包括口令验证协议PAP(Password Authentication Protocol)和挑战握手验证协议CHAP(Challenge-Handshake Authentication Protocol)。
LCP负责创建,维护或终止一次物理连接。NCP是一族协议,负责解决物理连接上运行什么网络协议,以及解决上层网络协议发生的问题。
下面介绍PPP链路建立的过程:
PPP链路状态机如图1所示。一个典型的链路建立过程分为三个阶段:创建阶段、认证阶段和网络协商阶段。
阶段1:创建PPP链路
LCP负责创建链路。在这个阶段,将对基本的通讯方式进行选择。链路两端设备通过LCP向对方发送配置信息报文(Configure Packets)。一旦一个配置成功信息包(Configure-Ack packet)被发送且被接收,就完成了交换,进入了LCP开启状态。
应当注意,在链路创建阶段,只是对验证协议进行选择,用户验证将在第2阶段实现。
阶段2:用户验证
在这个阶段,客户端会将自己的身份发送给远端的接入服务器。该阶段使用一种安全验证方式避免第三方窃取数据或冒充远程客户接管与客户端的连接。在认证完成之前,禁止从认证阶段前进到网络层协议阶段。如果认证失败,认证者应该跃迁到链路终止阶段。
在这一阶段里,只有链路控制协议、认证协议,和链路质量监视协议的packets是被允许的。在该阶段里接收到的其他的packets必须被静静的丢弃。
最常用的认证协议有口令验证协议(PAP)和挑战握手验证协议(CHAP)。 认证方式介绍在第三部分中介绍。
阶段3:调用网络层协议
认证阶段完成之后,PPP将调用在链路创建阶段(阶段1)选定的各种网络控制协议(NCP)。选定的NCP解决PPP链路之上的高层协议问题,例如,在该阶段IP控制协议(IPCP)可以向拨入用户分配动态地址。
这样,经过三个阶段以后,一条完整的PPP链路就建立起来了。
三、 认证方式
1)口令验证协议(PAP)
PAP是一种简单的明文验证方式。NAS(网络接入服务器,Network Access Server)要求用户提供用户名和口令,PAP以明文方式返回用户信息。很明显,这种验证方式的安全性较差,第三方可以很容易的获取被传送的用户名和口令,并利用这些信息与NAS建立连接获取NAS提供的所有资源。所以,一旦用户密码被第三方窃取,PAP无法提供避免