python基础之socket编程
python基础之socket编程
一、客户端和服务器架构
c/s架构和b/s架构
- c:client(客户端) s:server(服务器端) 比如电脑上安装的qq,微信
- b:browser(浏览器) s:server(服务器端) 比如,京东,天猫网页(这里不上app)
- s(服务器)端:有固定的ip,稳定一直在运行,支持并发(多线程)
- b/s架构也是c/s架构的一种
- c/s架构分为:硬件c/s架构(打印机)和软件c/s架构
1.1 学习网络编程的目的
学习网络编程的目的就是为了写一个cs架构的软件
- c(客户端)----------------网络-----------------s(服务器端)
- 就是完成c/s架构的开发
二、osi七层协议
-
网络:网络连接介质+网络协议(osi七层)
-
网络协议:osi七层协议:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层
-
五层协议:应用层,传输层,网络层,数据层,物理层
-
四层协议
2.1五层协议分析
-
物理层:010101这种电信号
-
数据链路层:
- 把物理层的电信号分组,每一组叫一个数据报/数据帧。每一个数据帧分成:报头head和数据data俩部分
- 每一个数据报,都有报头和数据部分。
- 报头:固定的18个字节 ,6个字节是发送者的地址,6个字节是接收者的地址,6个字节是数据类型
- mac地址:发送者、接收者的地址,就是mac地址
- 每块网卡都有一个唯一的mac地址,12位16进制数表示(前6位是厂商编号,后六位是流水编号)
- 广播:同一个局域网里进行通信,容易产生广播风暴
- 每一个数据报,都有报头和数据部分。
- 把物理层的电信号分组,每一组叫一个数据报/数据帧。每一个数据帧分成:报头head和数据data俩部分
-
网络层
-
ip:ipv4:32位2进制表示,点分十进制表示,从0.0.0.0到255.255.255.255,范围是有限的,不能表示出所有的网路设备,所以出现了ipv6
-
子网掩码:通过子网掩码和ip判断俩个ip是否处于同一个网段,通过ip地址和子网掩码做按位与运算
ip地址: 172.16.10.1: 10101100.00010000.00001010.000000001 子网掩码:255.255.255.0: 11111111.11111111.11111111.000000000 按位与运算:172.16.10.0 10101100.00010000.00001010.000000000 172.16.10.0/24包含了ip地址和子网掩码
-
ip跟mac有转换的关系
-
主机176.16.10.10.10/24访问172.16.10.11/24
-
ARP协议:广播的方式发售那个数据包,获取目标主机的mac地址
-
mac地址:查找学习mac地址和ip地址的映射表
-
第一次接收到就会在ip/mac映射表中添加一条数据{’172.16.10.11“:ddsadfgegsdgsdg}
-
-
-
任何一种协议都是由头部和内容的
-
-
传输层
tcp协议:
-
三次握手,四次挥手(重点),连接如何建立,发送数据如何保证可靠,断开如何断开,在建立连接过程中由状态。
-
服务的如果看到大量的syn_rcvd状态,请求同步收到状态
-
dos和ddos攻击:拒绝服务攻击,分布式的拒绝服务攻击
-
端口号:端口号的范围0~65535,0-1023位系统占用端口
udp协议:
- 发送,不需要响应,所以数据不可靠(比如看视频的 时候会花屏)
- 端口
- 通过ip和子网掩码唯一确定一台设备
- 通过ip和子网掩码维一以及端口号唯一确定一个软件。
-
-
应用层
三、上网流程分析
- 在浏览器输入www.baidu.com
- 会取dns服务器通过域名解析成ip地址
- 向ip+端口号这个地址发送请求,就会访问到百度的服务器
socket:在应用层和传输层之间的一个抽象层:它把TCP/TP层复杂的操作抽象为几个简单的接口供应用层调用已经实进程在网络中的通信。
四、简单的通信
#服务端
#导入一个socket模块
import socket
#想象成买手机打电话:socket.SOCK_STREAM 表示建立tcp连接 ,udp连接socket.SOCK_DGRAM
#买了个手机
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#插电话卡:绑定ip地址 传元组:(ip,端口号)
soc.bind(('192.168.11.146',8080)) #如果写本机ip,局域网外部可以访问
# soc.bind(('127.0.0.1',8080)) #如果写127.0.0.1,只能自己访问
#开机,监听,这个5 是半连接池的大小
soc.listen(5)
#等待别人给我打电话
print('xxxx')
conn,addr=soc.accept()
print('yyyy')
print(addr)
# conn 就是通路
#接收1024个字节
data=conn.recv(1024)
print('我收到客户端发的',data)
#conn.send 发送数据,数据必须是bytes格式
conn.send(b'xxxxx')
#挂断电话
conn.close()
#销毁手机
soc.close()
#客户端
import socket
#创建一个socket对象
soc=socket.socket()
#连接服务端
soc.connect(('192.168.11.146',8080))
#发送消息
soc.send(b'xxx')
data=soc.recv(1024)
print('我收到服务端回的',data)
#关闭连接
soc.close()