28、初识socket(subprocess模块)
经过近一个半月的学习我们已经度过了python基础的阶段,今天我们开始学习python网络编程,没有难以理解的逻辑,更注重的是记忆。
本篇导航:
对网络协议和基础没有概念的可以在阅读本文前预习计算机基础3、网络协议:http://www.cnblogs.com/liluning/p/7170799.html
一、客户端/服务器架构
1、C/S结构,即Client/Server(客户端/服务器)结构
2、我们在互联网中处处可见c/s架构比如说浏览器,qq,lol,视频软件。。。
3、我们学习socket就是为了c/s架构的开发
二、scoket与网络协议
首先我们需要实现网络通信必然需要多网络协议有着深刻的了解。而我们做开发如果把每一点都搞清楚太过于耗费精力,所以我们才有了scoket
socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的

三、套接字
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
1、基于文件类型的套接字:AF_UNIX
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
2、基于网络类型的套接字:AF_INET
还有AF_INET6被用于ipv6,还有一些其他的地址家族,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET
3、套接字函数的认识
首先我们要知道所有的函数使用都需要导入socket模块
1)socket()模块
import socket
获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2)服务端套接字函数
bind() 绑定(主机,端口号)到套接字
listen() 开始TCP监听
accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来
3)客户端套接字函数
connect() 主动初始化TCP服务器连接
connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
4)公共用途的套接字函数
recv() 接收TCP数据
send() 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
recvfrom() 接收UDP数据
sendto() 发送UDP数据
getpeername() 连接到当前套接字的远端的地址
getsockname() 当前套接字的地址
getsockopt() 返回指定套接字的参数
setsockopt() 设置指定套接字的参数
close() 关闭套接字
5)面向锁的套接字函数
setblocking() 设置套接字的阻塞与非阻塞模式
settimeout() 设置阻塞套接字操作的超时时间
gettimeout() 得到阻塞套接字操作的超时时间
6)面向文件的套接字函数
fileno() 套接字的文件描述符
makefile() 创建一个与该套接字相关的文件
四、基于tcp的套接字代码实现
前面一次性近二十个函数是不是看蒙蔽了 来看看实际应用其实应用很简单
tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
tcp服务端
ss = socket() #创建服务器套接字
ss.bind() #把地址绑定到套接字
ss.listen() #监听链接
while True : #服务器无限循环
conn,client_addr=ss.accept() #接受客户端链接
while True : #通讯循环
conn.recv()/cs.send() #对话(接收与发送)
conn.close() #关闭客户端套接字
ss.close() #关闭服务器套接字(可选)
tcp客户端
cs = socket() # 创建客户套接字
cs.connect() # 尝试连接服务器
while True : # 通讯循环
cs.send()/cs.recv() # 对话(发送/接收)
cs.close() # 关闭客户套接字
1、socket通信流程与打电话流程类似以此为例:
服务端:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
s.bind('127.0.0.1',8080) #手机插卡
s.listen(5) #开机 #print('starting...')
conn,addr=s.accept() #等电话 (链接,客户的的ip和端口组成的元组)
#print(conn,addr) data=conn.recv(1024) #接收
print('client data: <%s>' %data)
conn.send(data.upper()) #发送 conn.close() #挂电话
s.close() #关机
客户端:
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.connect(('127.0.0.1',8080)) #绑定手机卡 #发,收消息
phone.send('hello'.encode('utf-8'))
data=phone.recv(1024)
print('server back res:<%s>' %data) phone.close()
2、加上链接循环与通信循环
服务端:
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.bind(('127.0.0.1',8081)) #绑定手机卡
phone.listen(5) #开机 最多挂起5个服务 print('starting...')
while True: #链接循环
conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组)
print('-------->',conn,client_addr) #收,发消息
while True:#通信循环
try:
data=conn.recv(1024)
if not data:break #针对linux
print('client data: <%s>' %data)
conn.send(data.upper())
except Exception:
break
conn.close() #挂电话
phone.close() #关机
客户端(可以有几个客户端一起链接后面的被挂起前一个断开后立马链接):
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.connect(('127.0.0.1',8081)) #绑定手机卡 #发,收消息
while True:
msg=input('>>: ').strip()
if not msg:continue
phone.send(msg.encode('utf-8'))
data=phone.recv(1024)
print('server back res:<%s>' %data) phone.close()
3、模拟ssh远程模拟命令
服务端:
import socket
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8082))
phone.listen(5) print('starting...')
while True:
conn,client_addr=phone.accept()
print('-------->',conn,client_addr) while True:
try:
cmd=conn.recv(1024)
#if not cmd:break #针对linux
#执行cmd命令,拿到cmd的结果,结果应该是bytes类型
#。。。。
res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout=res.stdout.read()
stderr=res.stderr.read() #发送命令的结果
conn.send(stdout+stderr)
except Exception:
break
conn.close() #挂电话
phone.close() #关机
客户端:
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8082)) while True:
cmd=input('>>: ').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8'))
cmd_res=phone.recv(1024)
print(cmd_res.decode('gbk'))
phone.close()
五、异常解决(了解)

解决方法:
#加入一条socket配置,重用ip和端口 phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))
发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
vi /etc/sysctl.conf 编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30 然后执行 /sbin/sysctl -p 让参数生效。 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
linux系统方法
六、subprocess模块(简单介绍)
允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等
Popen类
subprocess模块中定义了一个Popen类,通过它可以来创建进程,并与其进行复杂的交互。查看一下它的构造函数:
__init__(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None, preexec_fn=None,
close_fds=False, shell=False, cwd=None, env=None,
universal_newlines=False, startupinfo=None,
creationflags=0)
主要参数说明:
args:args should be a string, or a sequence of program arguments.也就是说必须是一个字符串或者序列类型(如:字符串、list、元组),用于指定进程的可执行文件及其参数。如果是一个序列类型参数,则序列的第一个元素通常都必须是一个可执行文件的路径。当然也可以使用executeable参数来指定可执行文件的路径。
stdin,stdout,stderr:分别表示程序的标准输入、标准输出、标准错误。有效的值可以是PIPE,存在的文件描述符,存在的文件对象或None,如果为None需从父进程继承过来,stdout可以是PIPE,表示对子进程创建一个管道,stderr可以是STDOUT,表示标准错误数据应该从应用程序中捕获并作为标准输出流stdout的文件句柄。
shell:如果这个参数被设置为True,程序将通过shell来执行。
env:它描述的是子进程的环境变量。如果为None,子进程的环境变量将从父进程继承而来。
实例化:
res = subprocess.Popen(r'dir', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
28、初识socket(subprocess模块)的更多相关文章
- python笔记-9(subprocess模块、面向对象、socket入门)
一.subprocess 模块 1.了解os.system()与os.popen的区别及不足 1.1 os.system()可以执行系统指令,将结果直接输出到屏幕,同时可以将指令是否执行成功的状态赋值 ...
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
- python day 9: xlm模块,configparser模块,shutil模块,subprocess模块,logging模块,迭代器与生成器,反射
目录 python day 9 1. xml模块 1.1 初识xml 1.2 遍历xml文档的指定节点 1.3 通过python手工创建xml文档 1.4 创建节点的两种方式 1.5 总结 2. co ...
- Python中使用subprocess模块远程执行命令
使用subprocess模块执行远程命令 服务端代码 1 import socket 2 import subprocess 3 4 sh_server = socket.socket() 5 sh_ ...
- python学习道路(day7note)(subprocess模块,面向对象)
1.subprocess模块 因为方法较多我就写在code里面了,后面有注释 #!/usr/bin/env python #_*_coding:utf-8_*_ #linux 上调用python脚 ...
- 循序渐进Python3(八) -- 0 -- 初识socket
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Un ...
- s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译
时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...
- 1、初识socket
经过近一个半月的学习我们已经度过了python基础的阶段,今天我们开始学习python网络编程,没有难以理解的逻辑,更注重的是记忆. 对网络协议和基础没有概念的可以在阅读本文前预习计算机基础3.网络协 ...
- python网络编程--粘包解决方案 和 subprocess模块
1.缓冲区:作用:将程序和网络解耦分为输入缓冲区, 输出缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先 ...
随机推荐
- python全栈开发day67--字段类型、字段属性、ORM回顾
一.回顾总结 https://www.cnblogs.com/maple-shaw/articles/9323320.html 1. 视图 1. CBV 和 FBV from django.views ...
- AtCoder Regular Contest 082 (ARC082) E - ConvexScore 计算几何 计数
原文链接http://www.cnblogs.com/zhouzhendong/p/8934254.html 题目传送门 - ARC082 E 题意 给定二维平面上的$n$个点,定义全集为那$n$个点 ...
- P1233 木棍加工 dp LIS
题目描述 一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的.棍子可以被一台机器一个接一个地加工.机器处理一根棍子之前需要准备时间.准备时间是这样定义的: 第一根棍子的准备时间为1分钟: 如果刚处理 ...
- Linux下C语言的进程控制编程
代码: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/ty ...
- Java版本翻转字符串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1282题目描述: Java中的StringBuilder有一个字符串翻转函数,因此,可以先将输入的数字转 ...
- Python多重继承顺序---C3算法
什么是多重继承C3算法 MRO即 method resolution order (方法解释顺序),主要用于在多继承时判断属性的路径(来自于哪个类). 在python2.2版本中,算法基本思想是根据每 ...
- nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
在重启nginx服务的时候,出现了这个错误. [root@izuf68g6a94fj32w0afx00z etc]# nginx -c /var/run/nginx/nginx.pid nginx: ...
- puppeteer 安装失败的解决方案
你应该也是在玩puppeteer,所以才会来到这里寻找答案,开始正文…… 安装时遇到 ERROR: Failed to download Chromium r515411! Set "PUP ...
- 安装淘宝镜像cnpm时出现问题及解决方案
问题: 解决方案: 安装完成:
- python基础一 ------利用生成器生成一个可迭代对象
#利用生成器生成一个可迭代对象#需求:生成可迭代对象,输出指定范围内的素数,利用生成器产生一个可迭代对象#生成器:本身是可迭代的,只是 yield 好比return返回,yield返回后函数冻结状态, ...