要了解socket,首先要了解TCP/IP四层模型。
1.TCP/IP四层模型
TCP/IP四层模型是对OSI七层模型的简化,其自顶向下包含四层,分别是应用层、传输层、网络层、链路层。其中的每一层都有若干规则保障其与上下层级进行交互,也就是协议,进行通信的双方必须遵循协议才能顺利、高效的收发数据。在这些协议中,位于传输层的TCP协议和位于网络层的IP协议是使用频率最高,适用范围最广的协议,因此TCP/IP四层模型中的协议被统称为TCP/IP协议族。

2.什么是socket?
socket是位于应用层和传输层中间的中介,向上,socket负责接收应用层进程将要通过网络发出的数据和传递由网络过来发给进程的数据;向下,socket负责接收传输层发送过来的数据和发送进程将要利用网络发出的数据。socket可以看作是网络通信两端的接口,在Linux中,其本质是一种文件,记录了端的相关信息。也就是说,应用层和传输层之间不会直接面对面交流,而是通过socket以统一的、安全的方式进行网络数据传输。
为什么Linux中的socket被视作一种文件类型?
在Linux中所有的文件都有文件描述符,socket被视为一种文件的好处就在于Linux系统可以通过文件描述符,像操作一般文件一样操作socket,这就保持了Linux操作文件和socket的统一性。
3.socket有什么类型?
socket套接字存在多种类型,我们常用的是DARPA Internet套接字。根据数据的传输方式,Internet套接字也存在多种类型,其中常见的有两种,即流格式套接字(SOCK_STREAM)和数据报格式套接字(SOCK_DGRAM)
流格式套接字(SOCK_STREAM):
流格式套接字底层遵循TCP协议,因此其具有TCP协议的诸多特点,即不丢失,不乱序,异步收发(即数据的发送和接受不是同步的,TCP中数据可能分批到达,可以等待全部数据到达后再统一接收,这由TCP设置的缓冲区来保证)
在http协议中所使用的就是流格式套接字,因为html文件必须准确无误的被加载。
数据报格式套接字(SOCK_DGRAM):
数据报格式套接字底层遵循UDP协议,因此其具备UDP协议的特点,即可丢失损毁,限制单次传输数据大小,同步收发(对比TCP的异步收发,UDP中要求送达的数据必须马上接收,无论其是否是一个完整数据的一部分)
4.socket地址
网络通信的本质是进程间通信,因此在进行网络通信的进程双方必须知道对方的进程端口号和IP等信息,socket地址就是一种记录这些信息的数据结构。
socket地址在socket网络编程API中是名为sockaddr的结构体,有两个成员:
1.sa_family表示通信双方的地址族
2.sa_data表示socket地址值。根据地址族的不同,对地址值的解读方式也就不同。

常用地址族及其对应的协议族:

宏 PF_* 和 AF_* 都定义在 bits/socket.h 头文件中,且后者与前者有完全相同的值,所以二者通常混用。
协议族对应的地址值解读方式:

由上表可知,14 字节的 sa_data 根本无法容纳多数协议族的地址值。因此,Linux 定义了新的通用的 socket 地址结构体-sockaddr_storage,这个结构体不仅提供了足够大的空间用于存放地址值,而且是内存对齐的:

同时,为了方便为sockaddr和sockaddr_storage赋值,定义了专用socket地址结构体。
5.专用socket地址和通用socket地址
因网络通信技术的发展,曾经的sockaddr无法兼容现代诸多协议下的数据,比如上文中IPv4的协议族,如果使用sockaddr结构体对其地址值赋值则相当麻烦(因为sa_data是一整块连续空间,需要把意义不同的数据放进去,则要设置0-1byte放端口号,2-5byte放IP地址),而IPv6协议族的地址值甚至无法用sockaddr装下。
因此现在sockaddr和sockaddr_storage都被视为一种通用的socket地址,而新定义了诸多专用于各个协议的专用socket结构体,在调用相关函数时需要将专用socket地址强制转换为通用socket地址类型。
具体来说,以socket API中的bind()函数为例,
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
其中第二个参数需要指定socket地址,形参类型为struct sockaddr*,而如果使用的是IPv4协议,则可以传递实参数据类型为struct sockaddr_in的结构,并进行强制类型转换:
struct sockaddr_in sinaddr;
bind(...,(struct sockaddr*)&sinaddr,...);
参考:
本文介绍了TCP/IP四层模型,包括应用层、传输层、网络层和链路层,并详细阐述了socket作为应用层与传输层之间的接口作用。socket在Linux中被视为一种文件,提供流格式套接字(TCP)和数据报格式套接字(UDP)两种类型。此外,还讲解了socket地址的重要性,包括sa_family和sa_data成员,以及专用和通用socket地址结构体的使用。
与socket地址&spm=1001.2101.3001.5002&articleId=125547620&d=1&t=3&u=34144eded4234dbca571548c23352753)
1310

被折叠的 条评论
为什么被折叠?



