Go的网络编程详解( 二 )


“网络层”出现以后,每台计算机有了两种地址,一种是MAC地址,另一种是网络地址 。两种地址之间没有任何联系,MAC地址是绑定在网卡上的,网络地址则是网络管理员分配的 。网络地址帮助我们确定计算机所在的子网络,MAC地址则将数据包送到该子网络中的目标网卡 。因此,从逻辑上可以推断,必定是先处理网络地址,然后再处理MAC地址 。
规定网络地址的协议,叫做IP协议 。它所定义的地址,就被称为IP地址 。目前,广泛采用的是IP协议第四版,简称IPv4 。IPv4这个版本规定,网络地址由32个二进制位组成,我们通常习惯用分成四段的十进制数表示IP地址,从0.0.0.0一直到255.255.255.255 。
根据IP协议发送的数据,就叫做IP数据包 。IP数据包也分为”标头”和”数据”两个部分:”标头”部分主要包括版本、长度、IP地址等信息,”数据”部分则是IP数据包的具体内容 。IP数据包的”标头”部分的长度为20到60字节,整个数据包的总长度最大为65535字节 。
传输层有了MAC地址和IP地址,我们已经可以在互联网上任意两台主机上建立通信 。但问题是同一台主机上会有许多程序都需要用网络收发数据,比如QQ和浏览器这两个程序都需要连接互联网并收发数据,我们如何区分某个数据包到底是归哪个程序的呢?也就是说,我们还需要一个参数,表示这个数据包到底供哪个程序(进程)使用 。这个参数就叫做”端口”(port),它其实是每一个使用网卡的程序的编号 。每个数据包都发到主机的特定端口,所以不同的程序就能取到自己所需要的数据 。
“端口”是0到65535之间的一个整数,正好16个二进制位 。0到1023的端口被系统占用,用户只能选用大于1023的端口 。有了IP和端口我们就能实现唯一确定互联网上一个程序,进而实现网络间的程序通信 。
我们必须在数据包中加入端口信息,这就需要新的协议 。最简单的实现叫做UDP协议,它的格式几乎就是在数据前面,加上端口号 。UDP数据包,也是由”标头”和”数据”两部分组成:”标头”部分主要定义了发出端口和接收端口,”数据”部分就是具体的内容 。UDP数据包非常简单,”标头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包 。
UDP协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到 。为了解决这个问题,提高网络可靠性,TCP协议就诞生了 。TCP协议能够确保数据不会遗失 。它的缺点是过程复杂、实现困难、消耗较多的资源 。TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割 。
应用层应用程序收到”传输层”的数据,接下来就要对数据进行解包 。由于互联网是开放架构,数据来源五花八门,必须事先规定好通信的数据格式,否则接收方根本无法获得真正发送的数据内容 。”应用层”的作用就是规定应用程序使用的数据格式,例如我们TCP协议之上常见的Email、HTTP、FTP等协议,这些协议就组成了互联网协议的应用层 。
如下图所示,发送方的HTTP数据经过互联网的传输过程中会依次添加各层协议的标头信息,接收方收到数据包之后再依次根据协议解包得到数据 。

Go的网络编程详解

文章插图
二 socket编程Socket是BSD UNIX的进程通信机制,通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄 。Socket可以理解为TCP/IP网络的API,它定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序 。电脑上运行的应用程序通常通过”套接字”向网络发出请求或者应答网络请求 。

经验总结扩展阅读