Jack:计算机如何进行通信?
我:我可以告诉你带Linux操作系统的计算机如何进行通信。
Jack:带Linux操作系统的计算机?这和不带操作系统的计算机有区别吗?
我:有的。
Jack:哦。那你说说带linux操作系统的计算机如何进行通信吧。
我:早期——tcp\ip还没有集成在BSD内核的时候。
Jack:草。不是讲解Linux的吗?怎么扯到BSD了。
我:这个是历史原因。BSD牛逼的时候,某黑客还在玩泥巴。
Jack:好吧。
我:那个时候,计算机与计算机之间是不能进行tcp\ip通信的。那个时候,更主要的方式,是同一台计算机内的进程间进行通信。
Jack:同一台计算机内的进程间进行通信?为什么同一台计算机内的进程间需要通信?
我:在Unix之前的早期操作系统偏向于大而全的超级软件系统。就是一个软件设计得非常复杂而且全面。而Unix正好相反,它遵守“分而治之”的思想。在这种思想之下,一个大的软件被分割成了很多个小的任务。各个小任务之间需要同步与互斥,自然涉及到进程间通信。
Jack:还是不太明白。
我:你可以看一下我即将要写的《Linux内核源代码分析——进程的领地之内存》,会帮助你明白的。多的不说了。在单机环境下,通信的方式很多:消息传递、同步、共享内存。具体你可以参考下W.Richard Stevens先生写的《UNIX Network Programming》。
Jack:那两台计算机之间如何才能进行通信呢?
我:我们只讨论两台计算机都安装了Linux操作系统的情况。而且,只用tcp/ip通信协议。
Jack:这有区别吗?
我:有的。两台计算机要进行通信,首先,两台计算机都要有一个网卡——这是根本,如果没有网卡,tcp\ip即便意淫出来了,也没有任何意义。
Jack:这个我明白。网卡是硬件基础,没有硬件基础,软件再怎么牛逼都没用。
我:但是,所有的通信都是以进程作为单位的。所以网卡必须要集成到操作系统里。
Jack:如何集成到操作系统里?
我:回忆一下《Linux内核源代码分析——插入之后会发生什么?》的第三个问题与《Linux内核源代码分析——控制台的故事(你的command是如何输入的?)》,你会找到启发的。
Jack:集成了之后呢?
我:简单的说,集成了网卡之后,需要解决的问题是,如何把接收到的数据传送到所需要的进程。比如一个redis的server端,Linux内核如何把数据传送到redis-server这个进程而不是传递给了init进程呢?
Jack:这个。。。
我:关键就在于tcp/ip的tcp。
Jack:你是说传输层?
我:传你妹儿啊。传输层这种官方说法基本上都是官话,对认识问题没有半点帮助。
Jack:那关键是什么呢?
我:关键就在于tcp层——在Linux内核的实现是socket机制,最关键的,是那个sock结构体。
Jack:sock结构体,不是socket结构体吗?
我:去翻一翻源代码吧。弄明白sock结构体与socket结构体关系,socket机制就基本上清楚了。