【Linux】Socket编程基础
1.理解源IP和目的IP地址
IP在网络中,用来标识主机的唯一性,但是这里要思考一个问题:数据传输到主机是目的吗?不是的,因为数据是给人用的。比如:聊天是人在聊天,下载是人在下载,浏览网页是人在浏览。
进程是人在系统中的代表,数据传输到主机不是目的,而是手段。到达主机内部,再交给主机内的进程,才是目的。
上网,只有两种行为:
1.从远端服务器获取数据;
2.本地数据上传到远端服务器。
网络通信的本质,其实是两个不同主机的进程在进行数据交互,就是进程间通信。但进程通信的前提是让不同的进程看到同一份资源。在这个场景下的同一份资源也就是:网络。
但是系统中,同时会存在非常多的进程,当数据到达目标主机之后,怎么转发给目标进程?这就要在网络的背景下,在系统中,标识主机的唯一性。
2.认识端口号
端口号(port)是传输层协议的内容。端口号,可以用来标识系统中唯一的一个网络进程。
- 端口号是一个2字节16位的整数;
- 端口号用来表示一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;
- IP地址+端口号能够表示网络上某一台主机的某一个进程;
- 一个端口号只能被一个进程占用。
【问题】端口号 vs pid
1.不是所有的进程,都要进行网络通信,所以不是所有进程都有端口号,但每个进程都有pid
2.从技术角度,pid是可行的,但是pid是一个系统的概念,pid变化了呢?网络也要跟着变。网络不想和系统产生太大的耦合度,所以这是一种解耦。
IP地址用来标识全网内唯一的一个主机,port表示该主机内唯一的一个网络进程,IP + port = 全网内唯一的一个网络进程。
(源IP,源port,目的IP,目的端口号),网络通信的本质,是全网内唯二的两个进程在进行进程间通信,我们用对方的IP和port标识对方的唯一性,socket = IP + port。
端口号范围划分
- 0-1023:知名端口号,HTTP,FTP,SSH等这些广为使用的应用层协议,他们的端口号都是固定的。就类似于现实生活中的特殊电话120、119等。
- 1024-65535:操作系统动态分配的端口号,客户端程序的端口号,就是由操作系统从这个范围分配的。
理解源端口号和目的端口号
传输层协议(TCP和udp)的数据中有两个端口号,分别叫做源端口号和目的端口号,就是在描述“数据是谁发的,要发给谁”。
3.传输层的典型代表
传输层是属于内核的,要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来进行网络通信。
认识TCP协议:
- 传输层协议
- 有连接
- 可靠传输
- 面向字节流
认识UDP协议:
- 传输层协议
- 无连接
- 不可靠传输
- 面向数据包
【理解】TCP(可靠) vs UDP(不可靠),那为什么还要保留UDP?
这里的可靠或者不可靠不能当作贬义词理解,要把它当成中性词,特点。
TCP可靠就意味着要做更多工作,复杂,占用资源更多。
4.网络字节序
内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大小端之分,那么如何定义网络数据流的地址呢?
- 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
- 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
- 因此,网络数据流的地址应该这样规定:先发出的数据就是低地址,后发出的数据就是高地址。
- TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节;
- 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接受数据;
- 如果当前发送主机是小端,需要将数据转成大端,否则就忽略,直接发送。
【问题】大端 vs 小端
大小端按照字节为单位,把数据低权值位存在低地址处,叫做小端;把数据高权值位存在低地址处,叫做大端。
低权值位->小权值位;低地址->小地址,小端,小小小。
5.Socket编程接口
网络通信的本质,其实是进程间通信。
system V——本地进程间通信
posix标准——网络通信,进程通信,也能进行本地通信。
socket会有很多的种类,来满足不同的应用场景。socket未来的接口,会有不同的通信接口规范。但是socket的设计者只想提供一种通信接口,既可以用来本地通信,又可以进行网络通信。
所以他设计了一个struct sockaddr,每次传入参数只需要传入这个结构体,但必须带有16位地址类型,是AF_INET,还是AF_UNIX.传入后在函数内部会自行判断是做本地通信还是网络通信。
这就是继承和多态。