套接字:通信端点
一、什么是套接字
套接字是一种具有之前所说的“通信端点”概念的计算机网络数据结构。
网络化的应用程序在开始任何通讯之前都必须要创建套接字。就像电话的插口一样,没有它就完全没有办法通信。
套接字起源于20世纪70年代加州大学伯克利分校版本的Unix,即人们所说的BSD Unix。因此有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。
一开始套接字被设计用在同一台主机上多个应用程序之间的通讯。这也被称作进程间的通讯,或IPC。套接字有两种,分别是基于文件型的和基于网络型的。
Unix套接字是我们要介绍的第一个套接字家族。其“家族名”为AF_UNIX(在POSIX.g标准中也叫AF_LOCAL),表示“地址家族:UNIX”。
包括python在内的大多数流行平台上都使用术语“地址家族(Address family)”及其缩写“AF”。
而老一点的系统中,地址家族被称为“域”或“协议家族”,并使用缩写“PF”而不是“AF”。
同样的,AF_LOCAL将会代替AF_UNIX,不过为了向后兼容,很多系统上,两者是等价的。Python自己则仍然使用AF_UNIX。
由于两个进程都运行在同一台机器上,而这些套接字是基于文件。所以,它们的底层结构是由文件系统来支持的。同一台电脑上,文件系统能够被不同的进程访问。
另一种套接字是基于网络的,它有自己的家族名字:AF_INET,或叫“地址家族:Internet”。还有一种家族AF_INET6被用于网际协议第6版(IPV6)寻址上。
还有一些其他的地址家族,运用在某些平台上,运用的非常少。所有地址家族中,AF_INET是使用最广泛的一个。
python2.5中加入了一种Linux套接字的支持:AF_NETLINK套接字家族让用户代码和和内核代码之间的IPC可以使用标准BSD套接字接口。
python只支持AF_UNIX、AF_NETLINK和AF_INET家族,大部分时候我们都是使用AF_INET。
二、套接字地址:主机与端口
如果把套接字比作电话的插口——即通信的最底层结构,那主机主机与端口就像区号与电话号码的一堆组合。
有了能打电话的硬件还不够,你还要知道你要打给谁,往哪打。一个因特网地址由网络通信所必须的主机和端口组成。
合法的端口范围为0-65535。其中小于1024的端口号为系统保留端口。
如果你使用的是Unix操作系统,那么就可以通过/etc/services文件获取保留的端口号(及其对应的服务/协议和套接字类型)。
三、面向连接与无连接
1.面向连接(TCP)
无论你使用那一种地址家族,套接字的类型只有两种。
一种是面向连接的套接字,即在通信之前一定要建立一条连接。这种通信方式也被称为“虚电路”或“流套接字”。
面向连接的通信方式提供了顺序的、可靠的、不会重复的数据传输,而且也不会被加上数据边界。
这也意味着,每一个要发送的信息,可能会被拆分成多份,每一份都会不多不少地正确地到达目的地,然后被重新按顺序拼装起来,传给正在等待地应用程序。
实现这种连接地主要协议就是传输控制协议(即TCP)。要创建TCP套接字就得在创建得时候指定套接字类型为SOCK_STREAM。
TCP套接字采用SOCK_STREAM这个名字,表达了它作为流套接字特点。
由于这些套接字使用使用网际协议(IP)来查找网络中的主机,所以这样形成的系统,一般会由这两个协议(TCP和IP)名的组合来描述,即TCP/IP。
2.无连接
与虚电路完全相反的是数据报型的无连接套接字。这意味着,无需建立连接就可以进行通讯。但这时,数据达到的顺序、可靠性及不重复性就无法保证了。
数据报会保留数据边界,这就表示,数据是整个发送的,不会像面向连接的协议那样被先拆分成小块。
使用数据报来传输数据就像邮政服务一样。邮件和包裹不一定会按他们发送的顺序到达。
事实上,它们还有可能根本到达不了,而且,在网络中报文甚至会重复发送,这也增加了复杂性。
之所以会用它,是由于面向连接套接字要提供一些保证,以及要维持虚电路连接,这都是很重的额外负担。
数据报没有这些负担,所以它更便宜,通常能提供更好的性能,更适合某些应用场合。
实现这种连接的主要协议就是用户数据报协议(即UDP)。
要创建UDP套接字就得在创建的时候指定套接字类型为SOCK_DGRAM。
由于这些套接字使用网际协议来查找网络中的主机,这样形成的整个系统,一般会由这两个协议(UDP和IP)名的组合来描述,即UDP/IP。
为什么TCP是可靠传输,而UDP是不可靠传输?
TCP在数据传输时,发送端先把数据发送到自己的缓存中,然后协议控制将缓存中的数据发往对端,对端返回一个ACK=1,发送端则清理缓存中的数据,对端返回ACK=0,则重新发送数据,所以TCP是可靠的。
而UDP发送数据,对端是不会返回确认信息的,因此不可靠。
补充:
POSIX:可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX)。
POSIX定义了操作系统应该为应用程序提供的接口标注,是IEEE(电气和电子工程师协会)为要在各种UNIX操作系统上运行的软件而定义的一系列APU标准的总称。