专栏名称: CSDN
CSDN精彩内容每日推荐。我们关注IT产品研发背后的那些人、技术和故事。
51好读  ›  专栏  ›  CSDN

从一个简单的聊天程序SimpleChat看VPN技术

CSDN  · 公众号  · 科技媒体  · 2017-05-04 11:02

正文

SimpleVPN写好了以后,感觉比较简单,我觉得只有简单的东西才经得起折腾,才能全民折腾,所以说SimpleVPN还不够简单,本文来一个更加简单的——展示一个超级简单的点对点聊天程序,而且还带简单加密。顺便,我们再来看下,到底什么是VPN以及怎样实现它。
       

QQ如今才刚刚行过成年之礼,典型的90后00前,却早已到了后浪把前浪拍到岸边的砍儿,果不其然,被10后的微信给逆袭了。好在都是腾讯的,这就把竞争收敛到了公司内部,不然这将意味着一个巨人的倒下,太可怕了。多年前,很多人逆向过QQ的协议,然后做了各种各样的第三方客户端,这在腾讯看来是在搞根据地抢饭碗,这是无法接受的,所以加强了各种安全措施,让你第三方无法接入这个私有化的QQ系统。此后,第三方的QQ软件渐渐消失了,只剩下了“腾讯QQ”。不过,在我看来,腾讯封闭QQ协议不见得是件好事,你能指望一个QQ终端能做出什么大动作呢?充其量腾讯QQ是一个非常棒的产品,但是微信出来之后呢?如果微信不是T家的呢...所以说啊,让所有人都接受T家的通讯协议才是真正的霸道,从业务侧不一定是这般,至少从网络侧看是这样的。这样一来,即便哪天阿里做出了新的社交产品,还是“基于腾讯的XXX协议,兼容QQv..版本,兼容微信v...版本”,你看那些伟大的公司,很多都贡献了一个协议或者规范,比如HTTP、HHTPS、SSL/TLS、Android……


除了QQ之外,还有一类软件是我们熟悉的,那就是迅雷和电驴。不管是QQ,还是迅雷、电驴,它们的共同点都是在TCP/IP网络之上重新构建了一个新的点对点网络,即P2P网络。所谓的P2P网络指的是网络中的节点都是对等关系,任意两个节点之间,一个节点和多个节点之间均可以对等通信。事实上,P2P根本就没有什么神奇的,我们最底层的IP网络就是一个P2P网络,任意两个节点之间都可以实现没有主从关系的单播通信,而一个节点和多个节点之间则可以用组播进行通信,只是IP名称早已有之,因此P2P就特指应用层的组网模式了。简单点说,如果说IP网络是在各种互通的链路层之上构建的一个点对点网络的话,那么P2P网络就是构建于TCP/IP之上的对点对网络。至于说这个点对点上跑什么,那就取决于网络构建者的意愿了。
       

如果在点对点网络上跑人与人之间互发的消息,那它就是个聊天软件,比如QQ,微信这种,如果在点对点网络上跑文件数据,那就是P2P下载,那它就是个P2P下载软件,比如迅雷,电驴这种,类似的,如果在点对点网络上跑IP数据报文或者以太帧,那它就是个Overlay技术,比如VXLAN、GRE这种,如果将以上这些Overlay数据进行加密,那它就是VPN。不管怎样,名称并不重要。
       

以上这些都不是本文的核心——本文的核心在于展示一下从VPN到聊天程序的过渡是多么简单。

       

在我之前的文章《假期跟我一起写一个点对点VPN-SimpleVPN详解》(http://blog.csdn.net/dog250/article/details/70945840)中,我展示了一个非常简单的点对点VPN框架,本文中,我来将它改成一个非常简单的聊天程序。功能如下:


  • 用户登录可以获取在线用户列表;

  • 用户登录后可以通知其它在线用户该用户登录;

  • 登录用户可以随时获取在线用户列表;

  • 登录用户可以给指定在线用户发送消息;

  • 支持在线用户间的群聊。


基本上,除了不支持留言,基本该有的都有了。我们来看下怎么改。

       

其实,TCP/IP任何层的对等通讯都是在“聊天”,只是类似社交软件中的聊天是在人与人之间进行的,而TCP/IP对等层“聊天”是协议与协议之间进行的。协议与协议之间的聊天需要一个寻址的过程,不管是DNS,IP路由,ARP解析,MAC/端口查找...都是为了确认并找到要把消息发给谁。而人与人之间的聊天在发消息之前也要在头脑中经过一个类似的过程,也就是说,当你按下回车键的那一刻,你已经很明确这条消息是发给谁的了,这与网络协议之间的对等通信完全不同,后者需要协议来完成寻址,而人则在自己的大脑中完成寻址过程,所以说,改法很简单:

1. 添加消息的发送和接收

chat程序直接接收用户的输入,而不是从TAP中读取以太帧,所以不需要tap_fd,改为con_fd了,其实就是console,因此需要将read_from_tap和write_to_tap改为
read_from_console和write_to_console:



2. 删除寻址和学习机制

由于寻址已经在人的大脑中完成,故不再需要寻址,因此去掉了以下的handler:



3. 增加在线用户列表显示功能

详见1的用户输入解析。当输入list的时候,会显示在线用户。


现假设有ID为1,2,3的3个用户登录系统,用户3输入list时,以下是输出:


ID:1 online
ID:2 online

然后同样在用户3的终端前输入2:aaaaaaaaaaaaaaaa,那么用户2的终端将显示:

From 3:aaaaaaaaaaaaaaaa

也许你会觉得这不像个聊天程序,那是因为它少一个漂亮的GUI,而我并不擅长这个。
------------------------
此时应该知道frame中sid,did这两个ID的作用了,它可以用来支持群聊,就跟它在VPN中支持组播一样...
        

关于这个的代码,我已经放进了github的SimpleVPN那个目录:https://github.com/marywangran/SimpleVPN/blob/master/SimpleChat.c
通过以上,我们可以看出,这类技术可以改头换面叫做任何不同的名称,关键还是看你怎么用它了。不管它叫VPN,管它叫chat,管它叫overlay吧,或者直接overlaychat。

       

其实,要什么VPN,如果你和你的QQ好友能把自己的QQ输入输出和本地的一个TAP网卡字符设备的输入输出对接起来,那大QQ就可以当成是一个VPN客户端,同样的,如果你用迅雷,电驴什么的来对接一个虚拟网卡传输以太帧或者IP报文而不是传输文件,那么迅雷,电驴构建出来的P2P网络就是一个VPN网络。

       

让我们来畅想一下如何来应景。在装了QQ的Windows机器上,有一个文件,它是“C:/Tap.frame”,针对它的读写实际上就是在读写TAP虚拟网卡设备,这个用Windows驱动非常容易办到。此时,我们把这个文件用QQ传送给好友,并且好友那边也有一个这样的文件,会怎样?我们岂不是通过QQ搭建了一条隧道吗?Overlay?嗯,是的,这叫做IP over QQ吧,或者Everything over APP?管它呢,名词不重要!

       

这是分层模型给我们带来的好处!只要你的IP报文或者以太帧在本地形成了,除了直接发送到网线上之外,还有别的运输方式,比如你可以用UDP将其送出,可以用一个新的IP,当然这些都是常规的。本文中,我们看到,你还可以用QQ、迅雷、电驴之类的软件将其送出,甚至,你可以用集装箱将其送出,这就是IP over集装箱技术。


本文来自CSDN博客:

http://blog.csdn.net/dog250/article/details/71076357