(day27)subprocess模块+粘包问题+struct模块+ UDP协议+socketserver
目录
昨日回顾
软件开发架构
C/S架构
Client:客户端
Server:服务端
优点
占用网络资源少,软件的使用稳定
缺点
用户在使用多个软件要下载客户端,软件每次更新用户也需要更新
用户体验差
B/S架构
Broser:浏览器
Server:服务端
优点
用户不需要下载多个客户端,以浏览器充当所有软件的客户端
缺点
网络资源占用较大,网络不稳定时,软件的使用也不稳定
网络编程
- 实现远程通信
- 物理连接介质:网卡等
- 互联网协议
互联网协议
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
物理层
- 基于电信号发送一堆二进制数据
数据链路层
把二进制数据交给"以太网协议"处理:
规定好电信号的分组方式
必须要有一个网卡
mac的地址
由12位唯一的编码
前6位:厂商号
后6位:流水号
以太网协议
- 广播,单播
- 弊端:广播风暴,无法跨局域网通信
交换机
让多台电脑连接在一起
互联网
让所有电脑都互联到一起
网络层
连接到互联的电脑都需要有一个IP地址
- IP地址
- 用于唯一标识计算机(局域网)具体位置
- 点分十进制
- 最小值:0.0.0.0
- 最最大值:255.255.255.255
传输层
TCP/UDP协议
TCP:流式协议
基于TCP协议进行通信,必须要创建双向通道
- 一个是客户端往服务端的管道
- 一个是服务端往客户端的管道
三次握手,四次挥手
反馈机制
客户端发送信息,服务端,必须返回确认机制,否则客户端会一直发送请求
应用层
- http(重点),ftp(了解)
socket套接字
# 服务端.py
import socket
server = socket.socket()
server.bind(('127.0.0.1',8888))
server.listen(5) # 半连接池
while True:
conn,addr = server.accept()
while True:
try:
data = conn.recv(1024).decode('utf-8') # recv数据从内存中获取
if data == 'q':
break
print(data)
conn.send(data.encode('utf-8'))
except Exception as e:
print(e)
break
conn.close()
# 客户端.py
import socket
client = socket.socket()
client.connect(('127.0.0.1'.8888))
while True:
msg = input('>>')
client.send(msg.encode('utf-8'))
if msg == 'q':
break
data = client.recv(1024).decode('utf-8')
print(data)
client.close()
今日内容
一、subprocess模块
可以通过代码执行操作系统的终端命令
并返回终端执行命令的结果
import subprocess
cmd = input('cmd>>>:')
obj = subprocess.popen(
cmd, # cmd命令
Shell = True,
stdout = subprocess.PIPE, # 返回正确结果
stderr = subprocess.PIPE # 返回错误结果
)
data1 = obj.stdout.read()
data2 = obj.stderr.read()
result = data1 + data2
print(result.decode('gbk'))
二、粘包问题
- 服务端第一次发送的数据,客户端无法精确一次性接受完毕,下一次发送的数据就与上一次数据粘在一起
- 无法预测对象需要接受的数据大小长度
- 多次连续发送数据量小,并且间隔时间短的数据一次性打包发送过去
TCP协议特性
TCP是一个流式协议,会将多次连续发送数据量小,并且间隔时间短的数据一次性打包发送过去
三、struct模块
解决粘包问题, 是一个可以将很长的数据的长度,压缩成固定的一个标记(数据包头)
- 必须先定义报头,发送报头,在发送真实数据
import struct # 打包压缩 # i:模式,会将数据长度压缩成4个bytes str = '1123fsgsdasfdasfaa' # 模拟客户端 # 包头 headers = struct.pack('i',len(str)) print(len(headers)) # 4 # 模拟服务端 # headers = conn.recv(4) datalen = struct.unpack('i',headers) # 元组(len(str),) print(data_len[0]) # len(str)既想发送文件,又想发送文件的描述信息
客户端发送字典给服务端
# 服务端.py import socket import json import struct server = socket.socket() server.bind( ('127.0.0.1', 9527) ) server.listen(5) while True: conn, addr = server.accept() while True: try: # 先接收报头 headers = conn.recv(4) # 解包获取真实数据长度 data_len = struct.unpack('i', headers)[0] # 获取字典数据真实长度 bytes_data = conn.recv(data_len) back_dic = json.loads(bytes_data.decode('utf-8')) print(back_dic) except Exception as e: print(e) break conn.close()# 客户端.py import socket import struct import json import time client = socket.socket() client.connect( ('127.0.0.1', 9527) ) while True: send_dic = { 'file_name': 'jason真实写真集.avi', 'file_size': 10000000 # 10G } # json序列化,并转码成bytes类型数据 json_data = json.dumps(send_dic) bytes_data = json_data.encode('utf-8') # 先做报头 headers = struct.pack('i', len(bytes_data)) client.send(headers) client.send(bytes_data) time.sleep(10)
四、UDP
UDP是一种传输协议
- 不需要建立双向通道
- 不会粘包
- 客户端给服务端发送数据不需要等待服务端返回接受成功
- 数据容易丢失,不安全
# 服务端
import socket
# SOCK_DGRAM:代表UDP
server = socket.scoket(type = socket.SOCK_DGRAM)
server.bind(('127.0.0.1',9527))
msg, addr = server.recvfrom(1024)
# 客户端
import socket
client = socket.socket(type = socket.SOCK_DGRAM)
server_ip_port = ('127.0.0.1',9527)
client.sendto(b'hello',server_ip_port)
五、QQ聊天室
基于UDP实现QQ聊天室
# 服务端
import socket
server = socket.socket(type = socket.SOCK_DGRAM)
server.bind(('127.0.0.1',9527))
while True:
msg,addr = server.recvfrom(1024)
print(addr)
print(msg.decode('utf-8'))
send_msg = input('服务端:')
server.sendto(send_msg.encode('utf-8'),addr)
# 客户端
import socket
client = socket.socket(type = socket.SOCK_DGRAM)
addr= ('127.0.0.1',9527)
while True:
send_msg = input('客户端1:')
client.sendto(send_msg.encode('utf-8'),addr)
back_msg ,addr= client.recvfrom(1024)
print(back_msg.decode('utf-8'))
六、SocketServer
python内置模块,可以简化socket套接字TCP/UDP服务端的代码
import socketserver
# 定义类
class MyTcpServer(socketserver.BaseRequestHandler)
# 重新父类的handler
def handler(self):
# 1. 接收消息
data = self.request.recv() # conn.recv(1024)
# 2. 给客户端发送消息
send_msg = input('服务端:').encode('utf-8')
self.request.send(send_msg)
if __name__= '__main__':
server = socketserver.TCPserver(('127.0.0.1',8888),MyTcpServer)
server.serve_forever()
(day27)subprocess模块+粘包问题+struct模块+ UDP协议+socketserver的更多相关文章
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
- 8.7 day28 网络编程 socket套接字 半连接池 通信循环 粘包问题 struct模块
前置知识:不同计算机程序之间的数据传输 应用程序中的数据都是从程序所在计算机内存中读取的. 内存中的数据是从硬盘读取或者网络传输过来的 不同计算机程序数据传输需要经过七层协议物理连接介质才能到达目标程 ...
- python网络编程-socket套接字通信循环-粘包问题-struct模块-02
前置知识 不同计算机程序之间数据的传输 应用程序中的数据都是从程序所在计算机内存中读取的. 内存中的数据是从硬盘读取或者网络传输过来的 不同计算机程序数据传输需要经过七层协议物理连接介质才能到达目标程 ...
- 网络编程基础:粘包现象、基于UDP协议的套接字
粘包现象: 如上篇博客中最后的示例,客户端有个 phone.recv(2014) , 当服务端发送给客户端的数据大于1024个字节时, 多于1024的数据就会残留在管道中,下次客户端再给服务端发命令时 ...
- day31——recv工作原理、高大上版解决粘包方式、基于UDP协议的socket通信
day31 recv工作原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据, For the opt ...
- UDP协议&socketserver模块
UDP协议&socketserver模块 一.UDP协议 1.1 UDP实现简单通信 服务器 ------------------------------------------------- ...
- socker通信-struct模块-粘包问题
Socket概念 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对 ...
- python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...
- scoket模块 粘包问题 tcp协议特点 重启服务器会遇到地址被占用问题
scoket()模块函数用法 import socket socket.socket(socket_family,socket_type,protocal=0) 获取tcp/ip套接字 tcpsock ...
随机推荐
- 使用JSP+Servlet+Jdbc+Echatrs实现对豆瓣电影Top250的展示
使用JSP+Servlet+Jdbc+Echatrs实现对豆瓣电影Top250的展示 写在前面: 有的小伙伴,会吐槽啦,你这个标题有点长的啊.哈哈 ,好像是的!不过,这个也是本次案例中使用到的关键技术 ...
- Centos7搭建Scrapy爬虫环境
写在前面 因为之前的爬虫环境一直是部署在我自己本地的电脑上的,最近,写了一个监控别人空间的爬虫,需要一直线上24小时运行,所有就打算云服务器上部署环境,也捣鼓了好一会才弄好,还是有一些坑,这里先记录一 ...
- Linux 中文打字软件 gtypist 光标错位解决
在windows 下有 金山打字和其他的跟打软件,在Linux下找到了 gtypist 为练习中文打字,该软件分为练习模式的速度测试模式,在gtypist-2.9.5版中会出现以下几个问题: 一是在练 ...
- Janus安装教程,ubuntu18.04系统
Janus安装教程,ubuntu18.04系统 本文介绍Jansu如何安装,操作系统为Ubuntu 18.04. (1)安装git 执行命令:“sudo apt-get install ...
- json入门初体验
json是JavaScript对象表示法,也是轻量级的文本数据交互格式,独立于语言,能够自我描述 json文本格式在语法上与创建JavaScript对象代码相同,多以json不需要解析器,js程序能够 ...
- JVM调优—Jstack
Java命令学习系列(二)——Jstack jstack是java虚拟机自带的一种堆栈跟踪工具. 功能 jstack用于生成java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线 ...
- Hadoop点滴-HDFS命令行接口
1.-help[cmd] 显示命令的帮助信息 ./hdfs dfs -help ls1 2.-ls(r) 显示当前目录下的所有文件 -R层层循出文件夹 ./hdfs dfs -ls /log/map ...
- Flume初见与实践
Photo by Janke Laskowski on Unsplash 参考书籍:<Flume构建高可用.可扩展的海量日志采集系统> --Hari Shreedharan 著 以下简称& ...
- 使用java的循环单向链表解决约瑟夫问题
什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...
- Docker下配置nacos
前言 近段时间在学dubbo,dubbo-admin死活装不上,无论是本地还是docker,所以把目光投向了其他配置中心,我选定的是阿里新开源的nacos. 正文 拉取镜像到本地docker dock ...