pythonNet day02
网络编程
网络目的 : 数据的传输
网络数据传输是一个复杂的过程
OSI 七层模型 --》 网络通信标准化流程
- 应用层 : 提供用户服务,具体内容由特定程序规定
- 表示层 : 数据的压缩优化
- 会话层 : 建立应用连接,选择传输层服务
- 传输层 : 提供不同的传输服务,流量控制
- 网络层 : 路由选择,网络互连
- 链路层 : 提供链路交换,具体消息以帧发送
- 物理层 : 物理硬件,接口,网卡,线路
osi七层模型优点 : 将功能分开,降低了网络传输中的耦合性,每一部分完成自己的功能。可以在开发和实施的过程中各司其职。实现高内聚和低耦合的功能。
高内聚 : 单个模块功能尽量单一
低耦合 : 模块之间尽量减少关联和影响
四层
- 应用层 : 应用层 表示层 会话层
- 传输层 : 传输层
- 网络层 : 网络层
- 物理链路层: 链路层和物理层
五层(tcp/ip模型)
- 应用层 : 应用层 表示层 会话层
- 传输层 : 传输层
- 网络层 : 网络层
- 链路层 : 链路层
- 物理层 : 物理层
协议(网络协议):在网络通信中,各方必须遵守的规定。包括建立什么样的连接,消息结构等
应用层 : TFTP HTTP DNS SMTP
传输层 : TCP UDP
网络层 : IP
物理层 : IEEE
网络基本概念
1、主机: "localhost" 表示本台计算机
网络上 : 只在本地测试使用
'localhost' '127.0.0.1'
如果想在网络上进行测试(自动使用本地可用网卡IP)
'0.0.0.0' '' '172.60.50.93'
查看本地 IP 网络信息
linux上: ifconfig
win上查看本地IP: ipconfig
ping www.baidu.com --->14.215.177.38(百度的IP地址)
获取计算机名称
socket.gethostname()
'tedu'
获取主机IP
socket.gethostbyname('localhost')
'127.0.0.1'
2、IP地址
在网络上用于区分一台计算
IPv4 : 点分十进制 e.g. 192.168.1.72 0-255
32位二进制表示
IPv6 : 128
网络连接测试命令: ping 172.60.50.92
特殊IP
127.0.0.1 本地测试IP
0.0.0.0 本地网卡通用IP
192.168.1.0 表示当前网段
192.168.1.1 表示网关
192.168.1.255 广播地址
获取服务器主机信息
socket.gethostbyaddr("www.baidu.com")
('127.0.0.1', [], ['119.75.213.61'])
主机 别名 IP地址
将ip十进制转化为二进制
socket.inet_aton("192.168.1.2")
b'\xc0\xa8\x01\x02'
将ip二进制转化为十进制
socket.inet_ntoa(b"\xc0\xa8\x01\x02")
'192.168.1.2'
域名 : 网络服务器IP地址的名称
url : 在网络上定位某个资源位置
3、端口号 :端口号是网络地址的一部分,在一个系统中每个网络应用监听不同的端口,以获取对应端口传输的信息
数字范围 : 1--65535
1--255 : 一些众所周知的端口
256--1023 : 系统应用
1024---65535 : 自用
推荐用 >10000 8888 9999 7777 6666
测试一个软件端口号
socket.getservbyname('mysql')
3306
socket.getservbyname('http')
80
socket.getservbyname('ssh')
22
传输层服务
面向连接的传输服务 ---》 tcp协议
传输特征:提供可靠的传输服务
可靠性表现: 数据在传输过程中,无失序,无差错,无重复,无丢失
* 传输过程中有建立和断开连接的过程
三次握手:建立数据传输两端的持续连接
1. 客户端向服务器发起连接请求(我可以牵你手吗)
2. 服务器收到连接请求进行确认,返回报文(可以)
3. 客户端收到服务器确认进行连接创建(牵手成功)
四次挥手:断开连接的两端,保证数据的传输完整
1.主动方发送报文,告知被动方要断开连接(我们分手吧,你准备好)
2.被动方返回报文,告知收到请求,准备断开(知道了)
3.被动方再次发送报文,告知准备完毕可以断开(你分手吧)
4.主动方发送报文完成断开(分手了)
适用情况:文件的上传下载,网络情况良好,需要必须保证可靠性的情况
比如 : 信息聊天,文件上传下载,邮件,网页获取
面向无连接的传输服务 ---》 udp协议
传输特征 :
* 不保证传输的可靠性
* 无需建立三次握手和四次挥手的连接断开过程
* 消息的收发比较自由,不受其他约束(请原谅我这一生放荡不羁爱自由)
适用情况 : 网络情况较差,对可靠性要求不高,收发消息的两端不适合建立固定连接
比如 :网络视频,群聊,发送广播
套接字----socket
socket模块的套接字属性
(s表示一个套接字对象)
s.type 获取套接字类型 # SocketKind.SOCK_STREAM 流式套接字
s.family 获取地址族类型 # AddressFamily.AF_INET 获取地址族类型
s.fileno() 获取套接字的文件描述符(每一个IO操作系统都会为其分配一个不同的正整数,该正整数即为此IO操作系统的文件描述符)
s.getsockname() 获取套接字绑定的地址 # ('192.168.191.3', 8888)
s.getpeername() 获取连接套接字另一端的地址 # ('192.168.191.3', 7826)
s.setsockopt(level,optname,value) 设置套接字选项,丰富修改原有套接字功能
参数: level 设置选项的类型 optname 每个选项类型中的子选项 value 为选项设置值
s.getsockopt(level,optname) 获取套接字选项的值
from socket import *
s = socket()
print(s.type) # SocketKind.SOCK_STREAM 流式套接字
print(s.family) # AddressFamily.AF_INET 获取地址族类型
print(s.fileno()) #
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 设置端口可重用
print(s.getsockopt(SOL_SOCKET,SO_REUSEADDR))# 获取选项值 1
s.bind(("192.168.191.3",8888))
print(s.getsockname()) # 获取绑定的地址 ('192.168.191.3', 8888)
s.listen()
c,addr = s.accept() # addr也是链接客户端的地址
print(c.getpeername()) # ('192.168.191.3', 7826)获取链接套接字客户端地址
data = c.recv(1024)
print(data) # b'i'
c.close()
s.close()
socket套接字编程
套接字:通过编程语言提供的函数接口进行组合,更简单的完成基于tcp和udp通信的网络编程
套接字的分类
流式套接字(SOCK_STREAM):传输层基于tcp的协议进行通信
数据报套接字(SOCK_DGRAM):传输层基于udp的协议进行通信
底层套接字(SOCK_RAM):访问底层协议的套接字
网络收发缓冲区
1、协调读写速度、减少和磁盘交互
2、recv和send实际上是从缓冲区获取内容,和向缓冲区发送内容
recv()特性
1、如果连接断开,recv会立即结束阻塞返回空字符串
2、当接收缓存区为空时会阻塞
3、如果recv一次接收不完缓冲区内容,下次会继续接收,确保数据不丢失
send()特性
1、如果另一端不存在还试图使用send进行发送则会产生BrokenPipError异常
2、当发送缓冲区满时会阻塞
本地套接字
作用:用于本地不同程序间的进行数据传输
本地套接字的创建流程
1、创建套接字对象
sockfd = socket(AF_UNIX,SOCK_STREAM)
2、绑定本地套接字文件,如果文件不存在,则自动创建文件(绑定套接字文件)
sockfd.bind(file)
判断一个文件夹下是否有某个文件 os.path.exists('./tcp_client.py')
删除一个文件 os.remove(file) os.remove(file)
3、监听 listen
4、接收发送消息 recv send
from socket import *
import os sock_file = './sock' # 使用哪个文件作为套接字文件 if os.path.exists(sock_file):# 判断文件是否已经存在
os.unlink(sock_file) sockfd = socket(AF_UNIX,SOCK_STREAM) # 创建本地套接字 sockfd.bind(sock_file) # 绑定
sockfd.listen(5) # 监听 while True:
c,addr = sockfd.accept() # 建立连接
while True:
data = c.recv(1024)
if not data:
break
print(data.decode())
c.close()
sockfd.close()
服务端
from socket import * sock_file = "./sock" # 确保通信两端用相同的套接字文件 sockfd = socket(AF_UNIX,SOCK_STREAM) # 创建套接字 sockfd.connect(sock_file) # 链接 while True:
msg = input("Msg>>")
if msg:
sockfd.send(msg.encode())
else:
break sockfd.close()
客户端
TCP粘包
产生原因:TCP传输采用字节流的方式,消息之间没有边界,如果发送的速度比接收速度快,会造成多次发送的内容被一次接收,形成意义上的误解即粘包
产生条件:当使用send快速的连续发送极有可能产生粘包
影响:如果每次发送的内容代表一个独立的意思,需要单独识别,就会产生粘包。但是如果多次发送的内容就是一个连续的整体,此时就不需要处理。
如何处理:
1、每次发送后加一个结尾标志,接收端通过标志进行判断
2、发送一个数据结构
3、每次发送中间有一个短暂的延迟(有一个间隔)
TCP接收多个客户端连接,且可以持续发送消息
from socket import * sockfd = socket(AF_INET,SOCK_STREAM) #创建套接字 sockfd.bind(('127.0.0.1',9999)) #绑定地址 sockfd.listen(5) #设置监听 while True: # 等待客户端连接
print("Waiting for connect...")
connfd,addr = sockfd.accept()
print("Connect from",addr)
while True: # 消息收发
data = connfd.recv(1024)
if not data:
break
print("Receive:",data.decode())
n = connfd.send(b"Receive your message")
print("send %d bytes"%n) connfd.close() # 关闭套接字 sockfd.close()
TCP-server
from socket import * sockfd = socket() #创建套接字 sockfd.connect(('127.0.0.1',9999)) #发起连接 while True: #消息收发 msg = input("Msg>>")
if not msg:
break
sockfd.sendall(msg.encode())
data = sockfd.recv(1024)
print(data.decode()) sockfd.close()
TCP-client
HTTP
http协议-->超文本传输协议 应用层协议,HTTP是基于TCP协议编码的。
用途:网页的获取,基于网站的数据传输,基于http协议的数据传输
特点
- 应用层协议。传输层使用TCP传输
- 无状态协议,不记录用户的通信内容
- http1.1---->http2.0 成熟稳定
工作模式:
使用http双方均遵守http协议规定发送接收消息体
请求方,根据协议组织请求内容给对象
服务方,收到内容按照协议解析
服务方,将回复内容按照协议组织发送给请求方
请求方,收到回复根据协议解析
HTTP请求格式
格式: 请求行\ 请求头\ 空行\ 请求体
1、请求行(熟悉格式及作用): 提供具体的请求类别, 请求内容
GET / index.html / HTTP/1.1
请求类别 请求内容 协议版本
请求种类 : GET 获取网络资源
POST 提交一定的附加数据,得到返回 结果
HEAD 获取响应头
PUT 更新服务器资源
DELETE 删除服务器资源
CONNECT 预留
TRACE 测试
OPTIONS 获取服务器性能
2、请求头 : 对请求内容的具体描述, 以键值对的形式对请求信息进行描述
e.g.
Accept: text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
3、空行
4、请求体 : 具体的请求参数
(GET参数,或者POST提交的内容)
HTTP响应格式
1、响应行 反馈具体的响应情况
HTTP/1.1 200 OK
版本信息 响应码 附加信息
响应码 :
- 1xx 提示信息 表示请求已经接受
- 2xx 响应成功
- 3xx 响应需要重新请定向
- 4xx 客户端错误
- 5xx 服务器错误
常见响应码 :
- 200 成功
- 404 请求页面不存在
- 401 没有访问权限
- 500 服务器发生未知错误
- 503 服务器暂时无法执行
2、响应头 对响应信息的具体描述
e.g.
Cache-Control: private
Connection: Keep-Alive
3、空行
4、响应体:将客户想要的内容进行返回
搭建HTTP本地服务器
做的是一个本地服务端,接收来自浏览器客户端的请求
# 返回第一行 GET / HTTP/1.1
- 接收http请求; 解析http请求
- 响应一个网页给客户端
from socket import * # 处理客户端请求
def handle(connfd):
request = connfd.recv(4096) # 接收请求 # 防止客户端断开request为空
if not request:
return
request_line = request.splitlines()[0] # 返回第一行 GET / HTTP/1.1
info = request_line.decode().split(' ')[1]
if info == '/':
with open('index.html') as f:
response = "HTTP/1.1 200 OK\r\n" # 响应行
response += "Content-Type:text/html\r\n" # 响应头
response += '\r\n' # 空行
response += f.read() # 响应体
else:
response = "HTTP/1.1 404 Not Found\r\n"
response += "Content-Type:text/html\r\n"
response += '\r\n'
response += "<h1>Sorry...</h1>" connfd.send(response.encode()) # 发送给浏览器 sockfd = socket() # 搭建tcp网络
sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sockfd.bind(('0.0.0.0',8000)) # 绑定地址
sockfd.listen(3) # 设置监听
while True:
connfd,addr = sockfd.accept() # 获取连接端和地址
handle(connfd) # 处理客户端请求
在浏览器输入地址:127.0.0.1:8888,即可得到网页显示!
pythonNet day02的更多相关文章
- python学习菜单
一.python简介 二.python字符串 三.列表 四.集合.元组.字典 五.函数 六.python 模块 七.python 高阶函数 八.python 装饰器 九.python 迭代器与生成器 ...
- 学习day02
day021.结构标记 ***** 做布局 1.<header>元素 <header></header> ==> <div id="heade ...
- 《Professional JavaScript for Web Developers》day02
<Professional JavaScript for Web Developers>day02 1.在HTML中使用JavaScript 1.1 <script>元素 HT ...
- 《javascript经典入门》-day02
<javascript经典入门>-day02 1.使用函数 1.1基本语法 function sayHello() { aler('Hello'); //...其他语句... } #关于函 ...
- tedu训练营day02
1.Linux命令 1.关机.重启 关机 :init 0 重启 :init 6 2.rm 1.rm -rf 文件/目录 r :递归删除文件夹内的子文件夹 f :强制删除,force 2.练习 1.在用 ...
- Python基础-day02
写在前面 上课第二天,打卡: 大人不华,君子务实. 一.进制相关 - 进制基础 数据存储在磁盘上或者内存中,都是以0.1形式存在的:即是以 二进制 的形式存在: 为了存储和展示,人们陆续扩展了数据的表 ...
- Python之路PythonNet,第四篇,网络4
pythonnet 网络4 select 支持水平触发 poll 支持水平触发 epoll epoll 也是一种IO多路复用的方式,效率比select和poll 要高一点: epol ...
- Python之路PythonNet,第三篇,网络3
pythonnet 网络3 udp 通信 recvfrom sendtofork 多进程并发threading 多线程并发socketserver 系统模块 套接字的属性 setsockopt g ...
- Python之路PythonNet,第二篇,网络2
pythonnet 网络2 问题: 什么是七层模型tcp 和udp区别三次握手和四次挥手************************************************** tcp ...
随机推荐
- Python的hasattr() getattr() setattr() 函数使用方法详解--转载
hasattr(object, name)判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False.需要注意的是name要用括号括起来 1 ...
- python 判断列表字符串元素首尾字符是否相同
def match_words(words): ctr = for word in words: and word[] == word[-]: ctr += return ctr print(matc ...
- Android:你好,androidX!再见,android.support
1.AndroidX简介 点击查看Android文档中对androidx的简介 按照官方文档说明 androidx 是对 android.support.xxx 包的整理后产物.由于之前的suppor ...
- SSM(Spring+SpringMVC+Mybatis)+Mysql 框架整合搭建流程以及其间注意事项
复习SSM框架,太久没用自己手动撘一个,发现自己还是有很多地方忘记了和没注意的事项... 首先,直接给出总流程: 零.引jar包 1.引包(或者写maven.pom) 一.数据库部分 设计数据库各表结 ...
- mybatis之org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'time' in 'class java.lang.String'
mybatis接口 List<String> getUsedCate(String time); 配置文件 <select id="getUsedCate" pa ...
- 本地Jdev Run PG报严重: Socket accept failed错误
严重: Socket accept failed java.net.SocketException: select failed at java.net.PlainSocketImpl.socketA ...
- bzoj1367
题解: 左偏树模板题 维护n/2的好多课左偏树 每一次加进来一个点的时候,只有一个点 然后每次中位数比前面小的时候,那么和前面合并 代码: #include<bits/stdc++.h> ...
- busybox microcom Segmentation fault
/********************************************************************************* * busybox microco ...
- nginx 只容许域名访问禁止掉 ip 访问
在原有 nginx server 的基础上再加上相同端口的配置 server { listen 80 default_server; server_name ...
- (译)KVO的内部实现
09年的一篇文章,比较深入地阐述了KVO的内部实现. KVO是实现Cocoa Bindings的基础,它提供了一种方法,当某个属性改变时,相应的objects会被通知到.在其他语言中,这种观察者模 ...