1.UNIX/Linux 中的 socket 是什么?
在Linux中有一个哲学叫做:一切皆为文件
所以在 UNIX/Linux 系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件。对这些文件的操作,等同于对磁盘上普通文件的操作。

同样对于一个网络连接,Linux也把它作为一个文件来处理。

文件描述符:为了区分打开的文件和没有打开的文件,Linux会给每个打开的文件分配一个文件描述符,这个文件描述符就是一个整数。
通常0表示标准输入,对应的就是键盘,1表示标准输出,对应的就是显示器。还有一个2对应标准错误。

可以通过socket()函数来创建一个网络连接,或者说打开一个网络文件,这个函数返回一个文件描述符,有了这个文件描述符之后我们就可以基于这个文件描述符来进行文件的读写操作了,甚至可以用read()来读取远程计算机传来的数据,用write()函数来向远程计算机发送数据。

2.套接字的两种重要的数据传输方式
a.流格式套接字(SOCK_STREAM)
SOCK_STREAM 是一种可靠的、双向的通信数据流,数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送。很显然,这种数据传输方式是基于TCP协议的。

特点:
数据在传输过程中不会消失
数据是按照顺序传输的;
数据的发送和接收不是同步的(有的地方也称“不存在数据边界”)。

流格式套接字的内部有一个缓冲区(也就是字符数组),通过 socket 传输的数据将保存到这个缓冲区。接收端在收到数据后并不一定立即读取,只要数据不超过缓冲区的容量,接收端有可能在缓冲区被填满以后一次性地读取,也可能分成好几次读取。

应用:浏览器中使用的http协议,传过来的数据必须确保正确可靠,否则对应的html将无法解析

b.数据报格式套接字(SOCK_DGRAM)
计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。也就是说传输的正确性不是可靠的,很显然是基于UDP协议的,但是不可靠的代价换来的是传输效率。一般的视频协议使用的就是数据报格式套接字。

特点:
强调快速传输而非传输顺序;
传输的数据可能丢失也可能损毁
限制每次传输的数据大小
数据的发送和接收是同步的(有的地方也称“存在数据边界”)。

SOCK_DGRAM 没有想象中的糟糕,不会频繁的丢失数据,数据错误只是小概率事件。

我们所说的 socket 编程,是站在传输层的基础上,所以可以使用 TCP/UDP 协议,但是不能干「访问网页」这样的事情,因为访问网页所需要的 http 协议位于应用层。