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'
>>> 
View Code

 

 

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]# 
View Code

 

 

 

 

 

 

                        

 

       

 

posted on 2018-06-20 21:45  微子天明  阅读(579)  评论(0编辑  收藏  举报

导航