您的位置:首页 > 运维架构 > Shell

从输入/输出的视角看TCP/IP(终端,shell以及X Window)

2019-05-10 22:22 399 查看
版权声明:本文为博主原创,无版权,未经博主允许可以随意转载,无需注明出处,随意修改或保持可作为原创! https://blog.csdn.net/dog250/article/details/90051722

TCP/IP是迄今为止IT领域最伟大的发明,没有之一。

是时候总结一篇散文了。

第二个TCP/IP协议栈构建好的当时,这便征服的起点。

如果我们仅从常规的通信的角度去理解TCP/IP,那么它可能和电话,电报,邮政系统这些没有本质的区别,至多算是这些东西的升级版。

如果我们把概念下沉到TCP/IP以下的层面,仅仅将TCP/IP看作是一条 逻辑上线缆 就显然就可以看见它的特别之伟大!

TCP/IP能将目之所及,手之所触,伸向无穷远的远方!

若要闻者彰,不必再顺风而呼,若要见者远,不必再登高而招。TCP/IP可以在一个水平的Level轻松走向无限的远方,彻底抛弃了蛮力。

在TCP/IP之前,世界需要蛮力,比如我们需要更好的镭射投影技术把影片投得更远更清晰,然而这些技术终究败于距离,在无限的空间面前,它们早早就会遭遇无法逾越的瓶颈。

换句话说,这些技术是不可扩展的,所以称之为蛮力技术,而TCP/IP则可以无限扩展!TCP/IP受到的限制,仅仅是光速本身。

试想,作为一个人,我们如何把声音传播到无穷远的地方,我们如何摸得到千里之外的物品,这受限于我们的器官。然而对于计算机或者任意一台机器而言,TCP/IP却可以让其从无穷远的地方去感知事物,来将TCP/IP也可能会嵌入到生物的体内!

本文我们不再基于传统的 分层模型对等层通信 的视角来解释TCP/IP,我们换一个视角来欣赏。

RDMA的概念或多或少很多人听说过,如果没有听说过,说说理念就能明白。

如何让设备的内存或者控制芯片长在设备之外,这里的问题其实是一个通信协议的问题,TCP/IP可以统一解决这个问题。

我们已经不止一次在硬件领域看到过同样的事情,比如以太网统一链路层,比如PCIe技术统一内部总线,比如USB技术统一外部总线,它们之间还或多或少地存在着种种交叠,比如交换式替代总线式,比如以太网和USB之间的竞争…

TCP/IP在软件领域与之类似,然而更为壮阔。

如何将影像投射到无穷远的地方,说来也简单,把数据装进一根电话线即可,那么如何再加点声音呢?再来一根电话线。再加点控制,再来一根…

如何将一台大型计算机计算产生的结果展示在一台显示设备上,并且还可以从这台显示设备上连接的外设接受输入。这种需求现在看来显得毫无意义。这多半是微软Windows操作系统的影响。

微软的Windows操作系统曾经占据了世界的每一个角落,这种操作系统的架构让人们觉得 一台计算机必须配备一个显示器和一套键盘鼠标是多么理所当然!

然而,事实上,这不是真正的计算机,这只能算个 胖终端

胖终端根本不是为联网而生的,什么事情都在本地做,这和TCP/IP的理念是背道而驰的。

如今,我们很少用PC机了,大家都使用手机,胖终端不攻自破,你的手机只是一个显示设备并且提供输入,真正的计算操作是在云机房里没有显示器和键盘的服务器上进行的,嗯,这就是当前的现实,这就是云计算的模式。

现在把时间推向微软统治世界前的20年,还没有PC的概念,彼时的计算机只是计算,并不包含显示设备和输入设备,显示设备和输入设备合在一起,叫做 终端 。计算机和终端可能分别位于不同的地方,它们之间需要建立网络连接,这种需求,直接促使了TCP/IP的诞生!

PC时代,Windows操作系统显然只是一个过客。

注意,TCP/IP从来都不是为了打电话而诞生的,因为当时的电话网已经非常完善,根本没有动机去涅槃再造,至于说什么分组交换网,那不过恰好是TCP/IP加以利用的一个核心技术罢了,即便没有分组交换那篇论文,TCP/IP也依然会诞生,因为 必须连接计算机和终端!

有必要讲一下 终端shell 的概念。

  • 终端:独立于计算机的一套软件或者运行简单系统的硬件,接受输入和展示输出。
  • shell:运行在计算机上的一个程序,真正处理处理输入,生成输出。

现在需求很明确,需要两个方向的连接:

  • 终端的到shell的输入
  • shell的输出到终端

如何把输入送到shell,如何从shell接到输出,TCP作为全双工传输层协议,满足这个需求!

多么优美的架构模型,简单,直接!

接下来可以将精力放到如何做一个 好终端 和如何做一个 好shell 了。终端和shell之间的连接,TCP的存在就不用操心了。哦,对了,还要设计一个连接终端和shell的应用层协议!

我来给出第一类三件套:

  • 协议:Telnet诞生了!之后就是SSH…
  • shell:bash/csh/zsh
  • 终端:VT100/xterm/…

接下来是一个操作过程:

  1. bash的命令提示符会被Telnet/TCP协议传输显示在一个接着键盘的VT100终端的屏幕上;
  2. 你在键盘输入一个ls回车,该ls字符和回车会被VT100终端收集,通过Telnet协议打包,通过TCP将这个包送到计算上运行的bash;
  3. bash接收到包,按照Telnet协议解析出ls命令,调用系统调用取得结果;
  4. 通过Telnet/TCP将这些结果传给VT100终端;
  5. VT100终端用Telnet协议解析包后,将其展示在操作者面前的屏幕上。

这是一个多么经典的过程,我们现在依然在用,只不过将Telnet换成了SSH。

难免的,需要显示图形,动画这种复杂的东西,仅仅供显示字符的VT100之类就不能满足需求,以至于光显示这些复杂的元素,就需要一台 独立的计算机 ,毕竟 显示复杂的元素 这件事本身就需要非常大的 计算量

这台负责显示负责图形元素的计算机再被叫做终端似乎有点不妥,但记住,仅仅是名字上的区别,它再复杂也不过是一台终端。

这台复杂的终端,就是X Server!

嗯,这就是X Window的概念范畴了。X Window是一个体系,它诞生于1983年前后,几乎和TCP/IP还有我自己同岁。

由于这个专门负责显示的复杂终端其业务分工非常明确,所以我们按照 以显示功能为主线 重新画上面的框图:


然后按照前面解释 终端shell 7ff7 的关系的方式,重新解释 X serverX Client 之间的关系:

  • X Server:独立于计算机的一套运行在有图形显示功能硬件上的软件,接受输入和展示输出。
  • X Client:运行在计算机上的一个程序,真正处理处理输入,生成输出,并且根据这些输出按照X协议将 指导X Server如何显示 的信息打包。当然,要想更纯粹些,也可以把shell功能剥离,然后用管道等进程间通信机制去连接真正的shell,比如一个bash,比如Xterm就是这么做的。

可见,X client不光具备shell的功能,更主要的是要 用X协议打包指导X Server如何显示 的信息。

对比上面字符终端的框图,你会发现X Window系统的Client/Server与字符终端的Client/Server是反的。如果我们把运行在计算机上的不管是Telnetd/SSHd还是某个X Client看作是 负责逻辑处理的进程 的话,它确实只有在字符终端的概念下才会被认为是 Server 因为它接受多个字符终端的连接,处理繁重的工作:

  • 连接管理
  • Session管理
  • Shell分配与管理

然而对于X Window系统则不同,在X Window的视角,是 X终端 承担繁重的工作:

  • 图形UI的渲染与显示
  • 窗口Session的管理
  • 连接管理

现在,我来给出第二类三件套:

  • 协议:X协议
  • X Client:Xterm/Xeyes…
  • X Server:X/XQuartz…

这下来到了彻底的X世界!

难道X Client一定需要一个shell吗?比如它必须要关联一个bash吗?非也!

看你如何理解shell了,它只是操作系统外面的壳子,一个GUI程序完全可以自己发起系统调用。于是,大多数的X Client是不需要关联bash之类的。它可能就是下面的这样: 在屏幕上显示图片11.png展示的皮鞋

按照这个架构,我们重新审视微软的Windows系统是什么。

Windows系统对X Window做了如下的手术:

  1. 将X/TCP/IP协议簇换成了VGA,PS/2,USB这种。
  2. 将X Server直接塞进了Windows操作系统内部,绕过了X Client。

VGA和PS/2能伸多长呢?

是时候演示了。

前面几个晚上,我编写了一个叫做SkinShoeDemo的程序,输入两张图片,一张大图片和一张小图片,大图片做窗口的轮廓,小图片做按钮的轮廓,然后展示出来。具体参见:
Java AWT/Swing实现不规则窗体和控件: https://blog.csdn.net/dog250/article/details/89885476
其中的 SkinShoeDemo.java 代码。

由于这个代码运行的结果是展示一个GUI,所以,按照常规的想法,为了测试这个代码,就需要将其部署在一台支持图形界面的系统机器上。我也确实是在ubuntu桌面系统中做的实验。

但这都是微软灌输给我们的思想。

现在我将 SkinShoeDemo.java 代码和 11.png(大皮鞋)22(小皮鞋).png 放到一台没有图形界面支持的CentOS机器上。编译之,java执行:

[root@localhost ~]# javac SkinShoeDemo.java
SkinShoeDemo.java:149: 警告: AWTUtilities是内部专用 API, 可能会在未来发行版中删除
com.sun.awt.AWTUtilities.setWindowShape(demo, demo.getSkinshoeShape(pixieImage));
^
1 个警告
[root@localhost ~]# java SkinShoe
SkinShoeDemo$1.class  SkinShoeDemo.class    SkinShoeDemo.java     SkinShoePanel.class
[root@localhost ~]# java SkinShoeDemo
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
at java.awt.Window.<init>(Window.java:536)
at java.awt.Frame.<init>(Frame.java:420)
at javax.swing.JFrame.<init>(JFrame.java:233)
at SkinShoeDemo.<init>(SkinShoeDemo.java:78)
at SkinShoeDemo.main(SkinShoeDemo.java:146)[root@localhost ~]#

按照上文的描述,我们的这个SkinShoeDemo程序就是一个X Client,它的逻辑就是显示一个皮鞋形状的窗口上面附带一个皮鞋形状的按钮。

是的,它需要一个X Server!

那么我希望我的MacOS宿主机做它的X Server。

由于MacOS也是类UNIX的,我觉得它是自带X Window系统的,然而它却走了微软的路子,为了性能摒弃了可扩展性和多用户操作!详情看这个:
关于 Mac 版 X11:https://support.apple.com/zh-cn/HT201341

无奈,我下载了XQuartz。并且按照X Server的相关约定,配置了它:

  • 取消了认证。
  • 让其侦听了TCP 6000端口

然后将CentOS的地址加入ACL白名单:

再执行java程序:

[root@localhost ~]# java SkinShoeDemo
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
at java.awt.Window.<init>(Window.java:536)
at java.awt.Frame.<init>(Frame.java:420)
at javax.swing.JFrame.<init>(JFrame.java:233)
at SkinShoeDemo.<init>(SkinShoeDemo.java:78)
at SkinShoeDemo.main(SkinShoeDemo.java:146)

这说明需要一个 DISPLAY 环境变量。按照X Window系统的说明,所谓的DISPLAY包含三个部分:

# XServer的IP:显示设备ID.屏幕ID
nodeIP:DeviceID.ScreenID

我的MacOS的IP是 192.168.56.1 ,显然它只有这一个设备,而且只有一个屏幕,那么DISPLAY的值就是:

192.168.56.1:0.0

再次执行:

[root@localhost ~]# export DISPLAY=192.168.56.1:0.0[root@localhost ~]#
[root@localhost ~]# java SkinShoeDemo >/dev/null # 不显示输出

以下是观感:

没有图形功能的CentOS通过X协议将皮鞋展示在拥有图形功能的MacOS上了。

【注意,我把大皮鞋脚尖处的阴影给修掉了,这样更加美观。】

过程中,X协议作为数据交换的协议:

我们稍微看一眼CentOS上的Java程序作为X Client是如何 请求X Server 绘制皮鞋的:

虽然,CentOS自己没有图形处理功能,但是通过X协议,X Window系统完美将图形GUI显示的任务交给了运行在MacOS上的X Server!

是不是只要具有图形处理能力的系统,均可以做X Server呢?答案显示是肯定的。

接下来我用Windows来做一番X Server。

下载Windows的X实现vcxsrv:
https://sourceforge.net/projects/vcxsrv/

Windows X-server based on the xorg git sources (like xming or cygwin’s xwin), but compiled with Visual C++ 2012 Express Edition. Source code can also be compiled with VS2008, VS2008 Express Edition and VS2010 Express Edition, although current project and makefile are not fully compatible anymore.

安装后非常简单的配置,按照上面一样的方法,将CentOS的DISPLAY改成 192.168.56.101:0.0 ,执行java程序,Windows上如下显示:

此时的Windows,只是CentOS的一个 显示终端

关于X Window系统的可玩性,还有很多。最经典的当属xeyes这种古老的玩具了。

有人会怼,Windows的远程桌面不也一样吗?嗯,是的,看起来差不多,但是那是 带着所有像素的桌面 而不是 “喂,帮我画一个3025的矩形,涂成红色”这么一个要求* 。

所以说,区别很明显:

  • 远程桌面:使用远端的元素进行显示,远端需要把图片传过来。
    无论用什么系统运行远程桌面客户端,显示的均是同样的一个桌面。因为桌面快照是原封不动传输过来的,那本来就是它自己的桌面(当然,会有优化,压缩,捆绑,差分传输这些)。
  • X Server:使用本地元素进行显示,远端只需要将要求传递过来。
    不同的GUI系统对待同一个显示要求,显示结果的观感可能会不一样。X Server拥有对X Client请求的解释权。

X Window作为一个终端系统,要比其它所有的 在远端显示一些东西 的系统通用,轻量,且强大的多。

如果说有100台机器同时分别输出1个图形,现在需要将这100个图形进行统一视角的观察,难道上100个桌面吗?直接用X Window系统在一个大屏幕上显示这100个图形就好了嘛,别的什么额外的都不用。就比如说,只显示100双皮鞋。

X Window系统是第一批大规模使用TCP/IP的系统。UNIX系统从一开始便采用X Window系统来进行GUI展示,将计算和显示彻底分开,这种清爽的架构一路走到了今天的云计算时代。

广义地讲,后面几乎统治整个互联网的HTTP协议,确实和X协议太像了,计算和显示相分离:

  • 没有GUI支持的Web服务器将HTML/JS文本文件传输给浏览器;
  • 浏览器按照HTML/JS规范将文本内容渲染成好看的GUI元素。

说起模式嘛,世界上也就那么多,组合组合,都是组合。

是TCP/IP造就了今天无限扩展的互联网,together with微处理器技术的发展。最终,整个世界的所有节点组成了一台超级计算机,这就是互联网本身!

试想,如何按照微软Windows胖终端的思路,那将是多么令人遗憾的结局。能在本地进行的工作就绝对不会在远端进行,这是彻底的反互联网思路。这种思路让一切东西趋向于集中而不是分布化,这与互联网前身阿帕网的理念是背道而驰的,当然了,肯定无法承受来自苏联的核打击…

我并没有在黑微软的意思,我黑的是微软的Windows。

相反,我倒是觉得微软这家公司仍然是大有可为。说点题外话吧。

如今,与互联网失之交臂的微软也在拥抱互联网了,不管是出于利益考虑还是真的在涅槃重生,微软的大生态战略一直都是非常棒的。

我甚至觉得将来有一天Linux内核将会由微软来经营。我们知道,Linux内核的成就也得益于TCP/IP。

TCP/IP是个孵化器!

无疑,脱袜子里纳斯是Linux内核社区不折不扣的教主,灵魂人物,但是我在怀疑随着脱袜子的逐年衰老到最终逝去,没有任何个人能有能力接管并hold住Linux内核。除了微软!这不,微软不已经把Github收入囊中了吗?要知道这也是基于脱袜子的作品构建的,最初就是用于管理Linux内核的。

从微软开始向Linux内核贡献patch开始,微软就已经盯上了Linux。最近,微软在Linux内核和开源方面的动作非常有趣:
Windows 将成为 Linux 最好的发行版?使用其 4.19 内核: https://news.html5.qq.com/share/552704919194435906

如果有一天Linux内核真的由微软经营了,它能经营好吗?不知道。看看Oracle经营的Java怎么样。现在问,如果当年Java没有交给Oracle,而是交给了开源社区,社区能经营得更好吗?也不知道…

好吧,谁会care…

林花谢了春红,太匆匆,想和你再去吹吹风,
胭脂泪,相留醉,几时重,风会带走一切短暂的轻松。

浙江温州皮鞋湿,下雨进水不会胖。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: