Python之路PythonNet,第一篇,网络1
pythonnet 网络1
ARPAnet(互联网雏形)---> 民用
ISO(国际标准化组织)--->网络体系结构标准 OSI模型
OSI : 网络信息传输比较复杂需要很多功能协同 --> 将功能分开,降低耦合度,让每个模块完成一定的功能
--->将这些模块按照一定的顺序进行组合,完成功能,调理清晰。
按照规定功能,顺序排列的体系结构:OSI模型
OSI 七层模型:
应用层: 提供用户服务, 例如处理应用程序,文件传输,数据管理
表示层: 做数据的转换和压缩,解压,加密等
会话层: 决定了进程间的连接建立,选择使用什么样的传输层协议
传输层: 建立网络连接,提供合适的连接传输服务,提供流量控制;
网络层: 控制分组传输,进行路由选择,网络互联;
链路层:提供链路交换,具体的数据收发;
物理层:物理硬件,具体的传输条件和传输接口;
实际操作:四层模型
应用层 : 应用层,表示层,会话层
传输层 : 传输层
网络层 : 网络层
物理链路层 : 链路层 ,物理层
七层 ----- 》
四层
应用层 (包含应用层 表示层 会话层)
传输层
网络层
物理链路层 (包含链路层和物理层)
五层(TCP/IP模型)
应用层 (包含应用层 表示层 会话层)
传输层
网络层
链路层
物理层
协议: 网络协议,几在网络传输过程中为保证通信正常而定制的都遵守的约定;
应用层协议:TFTP DNS FTP SMTP HTTP
传输层协议: TCP UDP
网络层协议: IP ARP ICMP
网络知识:
主机 主机名称 (计算机名 域名)
host
本地主机表示方法: IP
localhost 127.0.0.1 表示本机通信地址
0.0.0.0 表示在局域网内的可用主机IP
172.60.50.218 表示本机在网络上的标识
python获取主机名称:
import socket
socket.gethostname()
>>> socket.gethostname() 'shenzhen.com' >>> socket.gethostbyname('shenzhen.com') '72.5x.x.1x9' >>> socket.gethostbyname('localhost') '127.0.0.1' >>>
IP地址:
IPv4 点分十进制 192.168.1.11
三个点将IP分为四个部分每部分取值 0--255 ;
二进制 8*4 32位二进制表示;
IPV6 更多可用IP;
>>> socket.gethostbyaddr('localhost')
('localhost', ['localhost.localdomain', 'localhost6', 'localhost6.localdomain6'], ['::1'])
>>> socket.gethostbyaddr('shenzhen.com')
('a72-52-4-119.deploy.static.akamaitechnologies.com', [], ['72.52.4.119'])
主机名 主机别名 主机地址
IP地址转换为二进制;
socket.inet.aton('xxx') 将地址十进制转换为二进制
socket.inet_ntoa(b'xxx') 将地址二进制转换为十进制
>>> socket.inet_aton('192.168.1.10')
b'\xc0\xa8\x01\n'
>>> socket.inet_ntoa(b'\xc0\xa8\x01\n')
'192.168.1.10'
>>>
区别:这两个函数有第一个参数,AF_INET 表示转换IPV4类地址;AF_INET 6表示转换IPV6类地址;
inet_pton(socket.AF_INET, '192.168.1.10')
inet_ntop(socket.AF_INET,b'\xc0\xa8\x01\x0b' )
例:
>>> socket.inet_pton(socket.AF_INET, '192.168.1.11')
b'\xc0\xa8\x01\x0b'
>>> socket.inet_ntop(socket.AF_INET,b'\xc0\xa8\x01\x0b')
'192.168.1.11'
>>>
域名: 或联网服务器IP的地址, 方便使用;
端口号 : 是地址的组成部分,用于在一个系统中区分应用层程序
取值范围 1 -- 65535
使用 1-255 是众所周知的端口 256-1023 系统进程占用
1024--49151 登记端口 49152-65535 私有端口或者动态端口
推荐 >10000 8888 6666 9999
获取系统中某个网络服务程序的端口号;
>>> socket.getservbyname('ssh')
22
>>> socket.getservbyname('http')
80
>>>
子网掩码 : 与IP 配合使用用来确定当前的网段
字节序
小端序 : 低序字节存在低地址位
大端序 : 高序字节存在低地址位
网络统一 : 网络字节序 保证不同的主机按照相同方式发送接受解析数据
总结:
OIS 七层模型 五层 和 四层 每一层模型的功能
消息在网络中的传递大致流程
什么是主机
什么是协议,协议起什么作用
什么是 ip地址
什么是端口
什么是子网掩码 ,域名 和 字节序
########
传输层 提供的通信类型:
1, 面向连接的可靠服务 ---> TCP
TCP协议中规定: 1传输服务必须连接,
2参数数据必须保证可靠;
3传输结束必须断开连接;
建立连接(三次握手)
(1)客户端向服务端发送连接请求(发送一个试探性的标志字符给服务器);
(2)服务端接收到请求后告知客户端可以连接;
(3)再次告知服务器客户端已经收到回复,下面要开始发送具体消息;
数据的可靠性: 无重复 无丢失 无失序 无错误
断开连接过程(四次挥手)
(1)主动方 发送标准告知 被动方 要断开连接;
(2)被动方 返回相应的标志信息告知 主动方 我已接收到你的请求;
(3)被动方 会再次发送标志信息表上已经准备就绪可以断开;
(4)主动方 断开连接告知被动方;
使用情况 : 对传输质量要求较高,需要可靠的传输。
传输的数据量较大(比如传文件)不需要频繁的连接断开 ;
比如: qq消息,邮件发送,文件上传,账户登录
2, 面向无连接的不可靠的服务 UDP协议
不保证数据的完整性
数据的发送都是由发起端决定的,不考虑连接端情况;没有三次握手和四次挥手;
使用情况:对实时性要求较高;
网络情况不佳的时候;
对数据的准确型没有严格要求;
建立必要的非连接的情况(比如广播组播);
套接字(网络间进行通信的方式的名称)
在linux中演化为一种文件类型socket
套接字的分类:
(1)流式套接字:表示传输层使用tcp协议提供面向连接的传输服务;
(2)数据报套接字: 表示传输层使用udp 协议提供面向无连接的传输服务;
(3)原始套接字:一般只有底层协议测试(用不到)
基于tcp协议的socket编程:
服务端:
(1)创建一个tcp流式套接字;
socket(family = AF_INET, type = SOCK_STREAM, proto = 0)
功能: 创建一个套接字;
参数: family 协议族 类型(AF_INET, UNIX)
type 套接字类型 :SOCK_STREAM tcp流式套接字;SOCK_DGRAM upd数据报套接字; SOCK_RAM 原始套接字;
proto 子协议选项:一般为0
返回值:套接字对象;
(2)绑定本机的IP和端口;
bind(address)
功能:绑定本机的IP和端口号;
参数:是一个包含两个元素的元组,元组的第一个元素是主机名,第二个是使用的端口号;
e.g. ('',8888) ('localhost',8888) ('127.0.0.1',8888)
('0.0.0.0',8888) ('172.60.50.218',8888)
(3)将套接字变为可监听套接字;
listen(n)
功能:将套接字设置为监听套接字,并且设置一个连接等待队列;
参数: 是一个正整数 >=1
(4)套接字等待客户端请求;
accept()
功能:阻塞等待客户端的连接;
参数:无
返回值: 第一个返回值为 和客户端交互的套接字;第二个返回值为 连接进来的客户端的address;
(5)消息的收发;
recv(buffer)
功能: 接收网络消息
参数:正整数 表示一次接收从缓冲区中拿到的消息的字节数;
返回值:返回接收到的消息;
( 1,当接收的网络缓冲中没有内容时会阻塞; 2,当连接断开后,recv会结束阻塞返回一个空字符串)
send(data)
功能:方式网络消息;
参数: 要发送的内容;
返回值:时间发送的字节数;
(python3中要求send的内容必须为bytes格式)
sendall(data)
功能:发送网络消息;
参数:要发送的内容要求为bytes格式
返回值: 如果成功发送返回None,发送失败异常;
(6)关闭套接字;
close()
功能:关闭一个套接字
客户端
connect(adress)
功能:向服务器发起连接请求;
参数: address 是一个元组,即为要连接的服务器的地址;
主要点:(1)客户端和服务端的套接字类型相同;
(2)客户端就是用创建的套接字和服务器交互;
(3)recv和send要与服务器配合,避免recv死阻塞;
(TCP循环服务不能满足多个客户端同时发生请求的情况;它不允许某个客户端单独出去占有服务器资源)
练习:
1 ########server服务端######### 2 # cat tcp_server.py 3 #!/usr/local/bin/python3 4 5 from socket import * 6 7 HOST = '127.0.0.1' 8 PORT = 9999 9 ADDR = (HOST,PORT) 10 BUFFERSIZE = 1024 11 12 sockfd = socket(AF_INET, SOCK_STREAM) 13 14 sockfd.bind(ADDR) 15 16 sockfd.listen(5) 17 18 while True: 19 print('wait for connect....') 20 21 conn,addr = sockfd.accept() 22 print('connect from',addr) 23 while True: 24 data = conn.recv(BUFFERSIZE) 25 if not data: 26 break 27 print('connect:',data.decode()) 28 n = conn.send(b'Recv your message.\n') 29 print('send.. %d'%n) 30 conn.close() 31 32 sockfd.close() 33 34 35 #########client客户端############### 36 # cat tcp_client.py 37 #!/usr/local/bin/python3 38 39 from socket import * 40 import time 41 42 HOST = '127.0.0.1' 43 PORT = 9999 44 ADDR = (HOST,PORT) 45 46 connfd = socket(AF_INET,SOCK_STREAM) 47 48 connfd.connect(ADDR) 49 50 while True: 51 data = input('send>>>') 52 if not data: 53 break 54 connfd.sendall(data.encode()) 55 data = connfd.recv(1024) 56 print('client recv:',data.decode()) 57 58 connfd.close() 59 [root@shenzhen day03]#