python网络编程、套接字、HTTP协议
网络编程?网络目的 : 数据的传输 网络数据传输是一个复杂的过程 OSI 七层模型 --》 网络通信标准化流程
osi七层模型优点 : 将功能分开,降低了网络传输中的耦合性,每一部分完成自己的功能。可以在开发和实施的过程中各司其职。实现高内聚和低耦合的功能。 高内聚 : 单个模块功能尽量单一 四层?
五层(tcp/ip模型)
? 协议(网络协议):在网络通信中,各方必须遵守的规定。包括建立什么样的连接,消息结构等 应用层 : TFTP HTTP DNS SMTP ? 网络基本概念1、主机: "localhost" 表示本台计算机 网络上 : 只在本地测试使用 如果想在网络上进行测试(自动使用本地可用网卡IP) 查看本地 IP 网络信息 ping www.baidu.com? --->14.215.177.38(百度的IP地址) 获取计算机名称 获取主机IP 2、IP地址 IPv4 : 点分十进制 e.g. 192.168.1.72 0-255 IPv6 : 128 网络连接测试命令:?ping 172.60.50.92 特殊IP 获取服务器主机信息 将ip十进制转化为二进制 将ip二进制转化为十进制 域名?: 网络服务器IP地址的名称 3、端口号?:端口号是网络地址的一部分,在一个系统中每个网络应用监听不同的端口,以获取对应端口传输的信息 数字范围 : 1--65535 1--255 : 一些众所周知的端口 测试一个软件端口号 传输层服务?面向连接的传输服务 ---》 tcp协议? 传输特征:提供可靠的传输服务 * 传输过程中有建立和断开连接的过程 四次挥手:断开连接的两端,保证数据的传输完整 适用情况:文件的上传下载,网络情况良好,需要必须保证可靠性的情况 面向无连接的传输服务 ---》 udp协议 传输特征 : 适用情况 : 网络情况较差,对可靠性要求不高,收发消息的两端不适合建立固定连接 套接字----socketsocket模块的套接字属性(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) 获取套接字选项的值 1 from socket import * 2 s = socket() 3 print(s.type) # SocketKind.SOCK_STREAM 流式套接字 4 print(s.family) # AddressFamily.AF_INET 获取地址族类型 5 print(s.fileno()) # 376 6 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 设置端口可重用 7 print(s.getsockopt(SOL_SOCKET,SO_REUSEADDR))# 获取选项值 1 8 s.bind(("192.168.191.3",8888)) 9 print(s.getsockname()) # 获取绑定的地址 (‘192.168.191.3‘,8888) 10 s.listen() 11 c,addr = s.accept() # addr也是链接客户端的地址 12 print(c.getpeername()) # (‘192.168.191.3‘,7826)获取链接套接字客户端地址 13 data = c.recv(1024) 14 print(data) # b‘i‘ 15 c.close() 16 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() 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() HTTPhttp协议-->超文本传输协议? 应用层协议,HTTP是基于TCP协议编码的。 用途:网页的获取,基于网站的数据传输,基于http协议的数据传输 特点
工作模式: 使用http双方均遵守http协议规定发送接收消息体 请求方,根据协议组织请求内容给对象 服务方,收到内容按照协议解析 服务方,将回复内容按照协议组织发送给请求方 请求方,收到回复根据协议解析 HTTP请求格式格式:?请求行 请求头 空行 请求体 1、请求行(熟悉格式及作用):?提供具体的请求类别,请求内容 GET / index.html / HTTP/1.1 请求类别 请求内容 ? 协议版本 请求种类 :? ?GET 获取网络资源 2、请求头 : 对请求内容的具体描述,?以键值对的形式对请求信息进行描述 e.g. Accept: text/html 3、空行 4、请求体?: 具体的请求参数 (GET参数,或者POST提交的内容) HTTP响应格式1、响应行 反馈具体的响应情况 HTTP/1.1 200 OK
常见响应码 :
2、响应头 对响应信息的具体描述 e.g. 3、空行 搭建HTTP本地服务器?做的是一个本地服务端,接收来自浏览器客户端的请求 # 返回第一行 GET / HTTP/1.1
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 OKrn" # 响应行 response += "Content-Type:text/htmlrn" # 响应头 response += ‘rn‘ # 空行 response += f.read() # 响应体 else: response = "HTTP/1.1 404 Not Foundrn" response += "Content-Type:text/htmlrn" response += ‘rn‘ response += "<h1>Sorry...</h1>" connfd.send(response.encode()) # 发送给浏览器 sockfd = socket() # 搭建tcp网络 sockfd.setsockopt(SOL_SOCKET,1) sockfd.bind((‘0.0.0.0‘,8000)) # 绑定地址 sockfd.listen(3) # 设置监听 while True: connfd,addr = sockfd.accept() # 获取连接端和地址 handle(connfd) # 处理客户端请求 ?在浏览器输入地址:127.0.0.1:8888,即可得到网页显示! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 统计:优化python中的概率计算
- python – 整数除法:对于所有整数a,b,// b == int(a / b)为
- python – 仅当变量为True时才执行函数
- day31:socketserver&hashlib&hmac&TCP登
- Python动态生成中文验证码
- python – 指定groupby聚合后的列顺序
- python多线程模块threading使用范例代码
- Python实现定时备份mysql数据库并把备份数据库邮件发送
- python基础_文件操作实现全文或单行替换的方法
- SyntaxError: Non-UTF-8 code starting with '\