day23-网络编程之互联网基础,tcp/ip协议详细介绍
温故而知新
昨天我们讲了很多,现在回顾一下
1.多态和多态性
多态指的是一种事物的多种形态,在我们的类中指的就是多个子类继承一个父类,并都定制了一样名称的功能
多态性指的是,多态带来的好的性质,它统一了一种事物对某些功能的使用方法.增加了代码的灵活性和扩展性.
在python中还有一种可以硬性要求子类必须有父类的某种方法的功能,即abc
模块
abc模块的使用
import abc
class A(metaclass=abc.ABCMeta): # 该类不能被实例化
@abc.abstractmethod # 被这个装饰器装饰的方法子类必须定义
def talk(self):
pass
class b(A):
def talk(self):
print('b 叫')
2.鸭子类型
在python中是崇尚鸭子类型的,因为鸭子类型不继承与一个父类,只是规定每个类里面都定义的该方法名字也都一样.它只是一个风格,你也可以不遵从,但那样就失去了这个性质的好处.它来自一句话:只要你看起来像鸭子并且你走路像鸭子,那你就是鸭子.
3.反射
hasattr(obj,str) 判断obj对象内有没有str这个属性
getattr(obj,key) 获取到obj对象内的key这个属性的值
setattr(obj,key,value) 为obj对象增加/覆盖key这个属性的值
delattr(obj,str) 删除obj这个对象的str属性
4.内置方法
isinstance(obj,cls)
判断 obj这个对象是不是cls类的实例
issubclass(cls,type)
判断这个cls类是不是继承type这个类,即是不是type的子类
__str__
当打印对象时,自动触发,并且该方法必须要有返回值.返回值得是字符串的类型
__del__
当删除一个对象时了,自动触发. 一般用于回收资源.操作系统的资源
5.异常处理
异常是程序报错的一种提示,当一个异常抛出来,没有被处理时,会终止该程序的运行
报错分为俩种:语法报错和逻辑报错
语法的完整语法
try:
被监测代码1
被监测代码2
被监测代码3
except 错误类型1:
处理异常代码1
except 错误类型2:
处理异常代码1
except (错误类型3,错误类型4):
处理异常代码1
except exception: # 万能异常匹配
处理异常代码1
else:
被监测代码没有异常时
finally:
无论有无异常都会执行
断言和自定义抛出异常
if type(1) == str:
raise Exception("不是字符串类型")
assert type(1) == str
class my_type(Exception): # 这个为自定义的报错类型
pass
那到昨天我们的python基础就讲到这里结束了.
网络编程
今天我们学习新的知识点,网络编程
那网络套接字编程我们得先知道套接字编程
我们可以拿套接字编程做什么?
学习套接字编程的目的是为了开发一个C/S或者B/S架构的软件
C/S就是就是客户端和服务端,即一个C/S软件就是一个由客户端和服务端构成的软件
B/S软件就是由浏览器端和服务端构成的软件
那它们的区别就是,C/S中的C和S都得自己编写,那自己编写的好处就是可以自己定义规则,而麻烦点在与我不仅要写服务端的程序还要写客户端的软件,而B/S中的B是浏览器端,它只需要你学怎么使用浏览器端的使用方法即可,但是你得遵循别人的规则.而S是自己编写的
我们的客户端如果和服务端是在同一台机器上的话,这只能够玩玩单机游戏了.而我们现在的软件大部分都是基于互联网上工作的.
大概的流程为:
客户端 服务端
client ---------网络------------ server
浏览器 服务端
browser ----------网络---------- server
那我们可以发现,我们这俩端要想达到通信的要求,它们之间的介质是网络.
所以我们得知道什么是网络?
网络即我们的互联网, 互联网是由物理连接介质 和 通信协议组成
互联网 = 物理连接介质 + 通信协议
而物理连接介质指的是网口,交换机,路由器等实际存在的东西
而:通信协议指的就是这些物质之间进行传递时通信的介质.
即就和我们的送快递差不多,送快递就好比我们的数据,而商家就好比发送端,我们自己就好比接收端,快递不可能是直接由发送端传到了接受端,而是经历了一个个的快递站点,而这些站点就好比是我们的物理连接介质(交换机,路由器).
而快递站点也必须根据你在快递上写的信息(我们就是中文),信息有发送端的名字,还有接收端的名称,接收端的地址,等等,但是主要的通信数据还是我们的快递.而它们遵循的标准就是快递单上的标准,而计算机则是按照它们的标准.
那我们就来学学计算机的标准是什么?
osi七层协议
互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层
每层运行常见物理设备 名称
OSI七层协议数据传输的封包与解包过程 (这个很重要)
我们可以模拟一下这个传输的过程
我们的客户端现在有一个密码这个数据需要发送到服务器端,让其进行验证,这时候,我们的数据就从客户端的应用层开始,应用层将我们的数据打包封装丢给了客户端传输层,传输层再拿到我们的数据进行封装,给他再进行了依次封装,封装的信息为头和数据,头可以是tcp报头也可以是udp包头.然后将这个封装好的数据丢给了网络层,然后网络层又给其加了一个ip包头,然后再往下丢,又丢给了数据链路层.又为其加了一个帧头,然后再往下丢,丢给了物理层,物理层就将这个封装了好多次的数据变成二进制然后由网口往外发送,然后别的服务端就根据数据的信息,一层一层解析,看看是不是指向它的内部,当发现有一个阶段不是时,又将其封装回去,发送给下一个服务器,直到又一个服务器端全部解析完成.都是指向它的软件,那么那个软件服务器端就拿到了我们客户端的数据了.
tcp/ip五层模型讲解(我们写的程序就基于这个协议来讲)
我们将应用层,表示层,会话层并作应用层,从tcp/ip五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议
就理解了整个互联网通信的原理。
首先,用户感知到的只是最上面一层应用层,自上而下每层都依赖于下一层,所以我们从最下一层开始切入,比较好理解 每层都运行特定的协议,越往上越靠近用户,越往下越靠近硬件
2.3.1 物理层
物理层由来:上面提到,孤立的计算机之间要想一起玩,就必须接入internet,言外之意就是计算机之间必须完成组网
物理层功能:主要是基于电器特性发送高低电压(电信号),高电压对应数字1,低电压对应数字0
2.3.2 数据链路层
数据链路层由来:单纯的电信号0和1没有任何意义,必须规定电信号多少位一组,每组什么意思
数据链路层的功能:定义了电信号的分组方式
以太网协议:
早期的时候各个公司都有自己的分组方式,后来形成了统一的标准,即以太网协议ethernet
ethernet规定
- 一组电信号构成一个数据包,叫做‘帧’
- 每一数据帧分成:报头head和数据data两部分
head | data |
---|---|
head包含:(固定18个字节)
- 发送者/源地址,6个字节
- 接收者/目标地址,6个字节
- 数据类型,6个字节
data包含:(最短46字节,最长1500字节)
- 数据包的具体内容
head长度+data长度=最短64字节,最长1518字节,超过最大限制就分片发送
mac地址:
head中包含的源和目标地址由来:ethernet规定接入internet的设备都必须具备网卡,发送端和接收端的地址便是指网卡的地址,即mac地址
mac地址:每块网卡出厂时都被烧制上一个世界唯一的mac地址,长度为48位2进制,通常由12位16进制数表示(前六位是厂商编号,后六位是流水线号)
*广播:*
有了mac地址,同一网络内的两台主机就可以通信了(一台主机通过arp协议获取另外一台主机的mac地址)
ethernet采用最原始的方式,广播的方式进行通信,即计算机通信基本靠吼
2.3.3 网络层
网络层由来:有了ethernet、mac地址、广播的发送方式,世界上的计算机就可以彼此通信了,问题是世界范围的互联网是由
一个个彼此隔离的小的局域网组成的,那么如果所有的通信都采用以太网的广播方式,那么一台机器发送的包全世界都会收到,
这就不仅仅是效率低的问题了,这会是一种灾难
上图结论:必须找出一种方法来区分哪些计算机属于同一广播域,哪些不是,如果是就采用广播的方式发送,如果不是,
就采用路由的方式(向不同广播域/子网分发数据包),mac地址是无法区分的,它只跟厂商有关
网络层功能:引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址
IP协议:
- 规定网络地址的协议叫ip协议,它定义的地址称之为ip地址,广泛采用的v4版本即ipv4,它规定网络地址由32位2进制表示
- 范围0.0.0.0-255.255.255.255
- 一个ip地址通常写成四段十进制数,例:172.16.10.1
*ip地址分成两部分*
- 网络部分:标识子网
- 主机部分:标识主机
注意:单纯的ip地址段只是标识了ip地址的种类,从网络部分或主机部分都无法辨识一个ip所处的子网
例:172.16.10.1与172.16.10.2并不能确定二者处于同一子网
子网掩码
所谓”子网掩码”,就是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。比如,IP地址172.16.10.1,如果已知网络部分是前24位,主机部分是后8位,那么子网络掩码就是11111111.11111111.11111111.00000000,写成十进制就是255.255.255.0。
知道”子网掩码”,我们就能判断,任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。
比如,已知IP地址172.16.10.1和172.16.10.2的子网掩码都是255.255.255.0,请问它们是否在同一个子网络?两者与子网掩码分别进行AND运算,
172.16.10.1:10101100.00010000.00001010.000000001
255255.255.255.0:11111111.11111111.11111111.00000000
AND运算得网络地址结果:10101100.00010000.00001010.000000001->172.16.10.0
172.16.10.2:10101100.00010000.00001010.000000010
255255.255.255.0:11111111.11111111.11111111.00000000
AND运算得网络地址结果:10101100.00010000.00001010.000000001->172.16.10.0
结果都是172.16.10.0,因此它们在同一个子网络。
总结一下,IP协议的作用主要有两个,一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络。
ip数据包
ip数据包也分为head和data部分,无须为ip包定义单独的栏位,直接放入以太网包的data部分
head:长度为20到60字节
data:最长为65,515字节。
而以太网数据包的”数据”部分,最长只有1500字节。因此,如果IP数据包超过了1500字节,它就需要分割成几个以太网数据包,分开发送了。
以太网头 | ip 头 | ip数据 |
---|---|---|
ARP协议
arp协议由来:计算机通信基本靠吼,即广播的方式,所有上层的包到最后都要封装上以太网头,然后通过以太网协议发送,在谈及以太网协议时候,我门了解到
通信是基于mac的广播方式实现,计算机在发包时,获取自身的mac是容易的,如何获取目标主机的mac,就需要通过arp协议
arp协议功能:广播的方式发送数据包,获取目标主机的mac地址
协议工作方式:每台主机ip都是已知的
例如:主机172.16.10.10/24访问172.16.10.11/24
一:首先通过ip地址和子网掩码区分出自己所处的子网
场景 | 数据包地址 |
---|---|
同一子网 | 目标主机mac,目标主机ip |
不同子网 | 网关mac,目标主机ip2 |
二:分析172.16.10.10/24与172.16.10.11/24处于同一网络(如果不是同一网络,那么下表中目标ip为172.16.10.1,通过arp获取的是网关的mac)
源mac | 目标mac | 源ip | 目标ip | 数据部分 | |
---|---|---|---|---|---|
发送端主机 | 发送端mac | FF:FF:FF:FF:FF:FF | 172.16.10.10/24 | 172.16.10.11/24 | 数据 |
三:这个包会以广播的方式在发送端所处的自网内传输,所有主机接收后拆开包,发现目标ip为自己的,就响应,返回自己的mac
2.3.4 传输层(重点)
传输层的由来:网络层的ip帮我们区分子网,以太网层的mac帮我们找到主机,然后大家使用的都是应用程序,你的电脑上可能同时开启qq,暴风影音,等多个应用程序,
那么我们通过ip和mac找到了一台特定的主机,如何标识这台主机上的应用程序,答案就是端口,端口即应用程序与网卡关联的编号。
传输层功能:建立端口到端口的通信
补充:端口范围0-65535,0-1023为系统占用端口
tcp协议:
可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割。
以太网头 | ip 头 | tcp头 | 数据 |
---|---|---|---|
udp协议:
不可靠传输,”报头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。
以太网头 | ip头 | udp头 | 数据 |
---|---|---|---|
tcp报文
tcp三次握手和四次挥手
其中建立三次握手中的状态为:
SYN_SENT表示建立连接的发送状态,LISTEN表示监听状态,即在等待连接的一个过程.SYN_RCVD表示的是接收到建立连接的请求,发送的状态,ESTABLISHED表示准备建立ok的状态,最后一个ESTABLISHED也表示建立ok的状态.这时候,发送端和接收端俩个桥
都建立好了.
其中建立三次握手中的变量名为:
SYN seq = x 为 发送端向接收端发送的建立连接的信号表示变量名,seq的x表示的是其序列号,ack表示接收端收到了其建立连接的请求并回应它,再将自己要建立通道的请求一起发送给发送端,发送端收到后也回了一个通过请求的信息返回给接收端,这时候俩个通道就都搭建好了
tcp的四次挥手
四次握手中的状态为:
当发送端这边不需要传输数据的时候,发送端的 FIN_WAIT_1 的申请关闭通道的请求,然后接收端处于CLOSE_WAIT,表示等待接收发送端的关闭通道的请求,但是这个时候是还是有数据在传输的,因为发送端可能数据已经传输完毕了,但是接收端此时可能还没有完全将数据全部都接收了.所以接收端还会一个处理这些数据的时候,当处理完数据的时候,再发送确认它可以关闭通道的请求,然后发送端到接收端的那个通道就关闭了,然后接收端也将其的数据处理完之后又发生了一个请求关闭管道的一个请求,发送端接收到后也再讲这些数据处理一会,最后会了一个答应的回答返回给接收端,这时候俩个通道都关闭了.
下面有一篇别人对tcp三次握手和四次挥手的理解,讲的比较细致
推荐链接:https://www.cnblogs.com/qdhxhz/p/8470997.html
TCP有6种标示:SYN(建立联机) ACK(确认) PSH(传送) FIN(结束) RST(重置) URG(紧急)
一、TCP三次握手
第一次握手
客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN=1,同时随机生成初始序列号 seq=x,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状
态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。这个三次握手中的开始。表示客户端想要和服务端建立连接。
第二次握手
TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己随机初始化一个序列号 seq=y,此
时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。这个报文带有SYN(建立连接)和ACK(确认)标志,询问客户端
是否准备好。
第三次握手
TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。
TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。这里客户端表示我已经准备好。
思考:为什么要三次握手呢,有人说两次握手就好了
举例:已失效的连接请求报文段。
client发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达server,本来这已经是一个失效
的报文,但是server端接收到这个请求报文后,还是会想client发出确认的报文,表示同意连接。假如不采用三次握手,那么只要server发出确认,新的建立就连接了,但其实这个
请求是失效的请求,client是不会理睬server的确认信息,也不会向服务端发送确认的请求,但是server认为新的连接已经建立起来了,并一直等待client发来数据,这样,server的
很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生,server会因为收不到确认的报文,就知道client并没有建立连接。这就是三次握手的作用。
二、TCP数据的传输过程
建立连接后,两台主机就可以相互传输数据了。如下图所示(本篇博客图片都是引用它人图片):
1)主机A初始seq为1200,滑动窗体为100,向主机B传递数据的过程。
2)假设主机B在完全成功接收数据的基础上,那么主机B为了确认这一点,向主机A发送 ACK 包,并将 Ack 号设置为 1301。因此按如下的公式确认 Ack 号:
Ack号 = Seq号 + 传递的字节数 + 1 (这是在完全接受成功的情况下)
3)主机A获得B传来的ack(1301)后,开始发送seq为1301,滑动窗体为100的数据。
......
与三次握手协议相同,最后加 1 是为了告诉对方要传递的 Seq 号。上面说了,主机B完全成功接收A发来的数据才是这样的,如果存在丢包该如何。
下面分析传输过程中数据包丢失的情况,如下图所示:
上图表示通过 Seq 1301 数据包向主机B传递100字节的数据,但中间发生了错误,主机B未收到。经过一段时间后,主机A仍未收到对于 Seq 1301 的ACK确认,因此尝试
重传数据。为了完成数据包的重传,TCP套接字每次发送数据包时都会启动定时器,如果在一定时间内没有收到目标机器传回的 ACK 包,那么定时器超时,数据包会重传。
上面也只是一种可能,比如数据1250丢失,那么Ack返回的就是1250,具体的可以详细看下博客:【TCP协议】(1)---TCP协议详解,这里面滑动窗口有说明。
三、TCP的四次挥手
第一次挥手
TCP发送一个FIN(结束),用来关闭客户到服务端的连接。
客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),
此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
第二次*挥手*
服务端收到这个FIN,他发回一个ACK(确认),确认收到序号为收到序号+1,和SYN一样,一个FIN将占用一个序号。
服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器
通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个
状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
第三次*挥手*
服务端发送一个FIN(结束)到客户端,服务端关闭客户端的连接。
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,
此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
第四次*挥手*
客户端发送ACK(确认)报文确认,并将确认的序号+1,这样关闭完成。
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时
TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
思考:那么为什么是4次挥手呢?
为了确保数据能够完成传输。
关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也
即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢.
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到
FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能
发送FIN报文,因此不能一起发送。故需要四步挥手。
思考:客户端突然挂掉了怎么办?
正常连接时,客户端突然挂掉了,如果没有措施处理这种情况,那么就会出现客户端和服务器端出现长时期的空闲。解决办法是在服务器端设置保活计时器,每当服务器收到
客户端的消息,就将计时器复位。超时时间通常设置为2小时。若服务器超过2小时没收到客户的信息,他就发送探测报文段。若发送了10个探测报文段,每一个相隔75秒,
还没有响应就认为客户端出了故障,因而终止该连接。
四、SYN(洪水)攻击
背景
初始化连接的 SYN 超时问题Client发送SYN包给Server后挂了,Server回给Client的SYN-ACK一直没收到Client的ACK确认,这个时候这个连接既没建立起来,也不能算
失败。这就需要一个超时时间让Server将这个连接断开,否则这个连接就会一直占用Server的SYN连接队列中的一个位置,大量这样的连接就会将Server的SYN连接队列耗尽,
让正常的连接无法得到处理。
目前,Linux下默认会进行5次重发SYN-ACK包,重试的间隔时间从1s开始,下次的重试间隔时间是前一次的双倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第
5次发出后还要等32s都知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才会把断开这个连接。由于,SYN超时需要63秒,那么就给攻击者一
个攻击服务器的机会,攻击者在短时间内发送大量的SYN包给Server(俗称SYN flood攻击),用于耗尽Server的SYN队列。
什么是 SYN 攻击
SYN 攻击指的是,攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器
需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。SYN 攻击是一
种典型的 DoS攻击。
如何检测 SYN 攻击?
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的
netstats 命令来检测 SYN 攻击。
如何防御 SYN 攻击?
SYN攻击不能完全被阻止,除非将TCP协议重新设计。我们所做的是尽可能的减轻SYN攻击的危害,常见的防御 SYN 攻击的方法有如下几种:
缩短超时(SYN Timeout)
时间增加最大半连接数
过滤网关防护SYN
cookies技术
2.3.5 应用层
应用层由来:用户使用的都是应用程序,均工作于应用层,互联网是开发的,大家都可以开发自己的应用程序,数据多种多样,必须规定好数据的组织形式
应用层功能:规定应用程序的数据格式。
例:TCP协议可以为各种各样的程序传递数据,比如Email、WWW、FTP等等。那么,必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了”应用层”。
2.3.6 socket
我们知道两个进程如果需要进行通讯最基本的一个前提是能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大,这时候我们需要另辟它径了,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。
能够唯一标示网络中的进程后,它们就可以利用socket进行通信了,什么是socket呢?我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。
socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。
这三个图必须会画: