前言
菜某的笔记总结
内网IP与公网IP
首先,我们知道全球电脑数量众多,但是IP有限,所以我们无法每人分配一个IP。
应对这种情况,我们就出现了内网IP和外网IP。
首先我的公司为路由器注册了一个公网IP,那么外界对我们进行访问的话,就需要访问这个公网IP。
但是我们公司中又有许多电脑,所以我们的局域网又会为每个电脑分配一个内网IP。
但是,内网IP在外界是无法访问的,他只能通过发送到公网IP上,再经过一系列分析,发送到相应的主机上。
而且内网IP有重复的情况。
内网IP形式的潜规则
10.0.0.0------10.255.255.255
172.16.0.0------172.31.255.255
192.168.0.0------192.168.255.255
其他的形式基本都是公网IP
查取自己公网IP的方法:在百度中输入IP就出来了。
osi七层模型
物理层
打包以下的数据,转化为二进制
数据链路层
双方Mac地址
网络层
双方IP地址
传输层
指定双方的端口
会话层
负责与目标建立断开连接
表示层
对数据加密解密,编码
应用层
规定数据的协议格式(get,post)
原本数据
实际也就是数据包。
发送时需要一层层加包,接收时需要一层层解包。
在代码中的体现
import socket
#实例化对象
user=socket.socket
发送连接数据包
user.connect(('161.165.149.155',80))
#应用层
content='网站请求格式'
#表示层
content=content.encode('utf-8')
user.sendall(content)
rece=user.recv(1024)
print(rece.decode('utf-8'))
#会话传输
user.close()
UDP和TCP协议
UDP:不去建立连接,直接发数据,速度很快,但是并不能确保他们到达目的地,可能会出现数据为传达的情况。常常用在语音视频通话,游戏画面等场所。
TCP:发送和结束发送都需要发送特定数据包进行连接和断开,它能够确保数据发送到,如果没法送到,会自动重新发送。但是由于步骤多,所以传输的速度相对慢。常用于网站手机app。
UDP的代码写法
服务端
import socket
sever=socket.socket()
sever.bind(('127.0.0.1',9003))
data,(host,port)=sever.recvfrom(1024)#接收UDP形式数据
print(data,host,port)
客户端
import socket
client=socket.socket()
data=input("发送的内容")
client.sendto(data.encode('utf-8'),("127.0.0.1",9003))
#发送UDP型的数据
TCP的三次握手和四次挥手
三次握手:客户端发送我要连接,服务端返回同意,客户端返回我也能接收到你的消息
(代码层面实际上是生成一个数字让对方加一后返回)
当对面没返回应答,自己会重新发送
四次挥手:客户端说我想离开,服务端说我知道了等我处理一下信息,服务端说我处理完了可以断开了,客户端说可以我断开了。
粘包现象
生成原因:
网卡有一个缓冲区,我们发送都需要经过缓冲区,再由缓冲区进行传输。但是如果我们发送的太快,就会产生两个数据包合并了一个数据包。
send与sendall的区别
用socket的send函数发送时,在网卡部分可能会没地方了导致你的数据只存进去了一部分,所以用sendall的话会源源不断的进行发送,知道发送全了为止。
解决方法:
每次发消息前先发送4个字节,这四个字节发送你将发送消息的长度,然后你下一次接收数据只接受相应长度的字节,这样就会把包给区分开。
但是还会出现类似sendall这种没发全的情况,所以接收一方也要判断是否接收全,接受全了再干别的。
接收时,判断一下对方长度,接收一次最多只能接收1024*8个字节,那么应该设置个判断,如果大于了,就设置循环,如果不足,就规定接收相应的字节。
总结一下:
就是要对接收的信息长度进行判断,接收相应的长度即可。