大聊Python----SocketServer
什么是SocketServer?
SocketServer的最主要的作用是实现并发处理,也就是可以多个用户同时上传和下载文件。
socketserver模块简化了编写网络服务器的任务。
socketserver一共有这么几种类型
class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
这使用Internet TCP协议,该协议提供客户端和服务器之间的连续数据流。
class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)
它使用数据报文,这是离散的信息包,在传输过程中可能会无序到达或丢失。参数与TCPServer相同。
class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)
这些不常用的类与TCP和UDP类相似,但是使用Unix域套接字;它们在非unix平台上不可用。参数与TCPServer相同。
在继承关系图中有五个类,其中四个代表四种类型的同步服务器:
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
创建一个socketserver 至少分以下几步:
1、首先,必须通过子类化BaseRequestHandlerclass并重写其handle()方法创建一个请求处理程序类;此方法将处理传入的请求。
2、其次,必须实例化一个服务器类,将服务器的地址和请求处理程序类传递给它。
3、然后调用服务器对象的handle_request() orserve_forever()方法来处理一个或多个请求。
4、最后,调用server_close()来关闭套接字
## server.py ## import socketserver class MyTCPHandler(socketserver.BaseRequestHandler): # 定义MyTCPHandler这个类
"""
The request handler class for our server. It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
""" def handle(self): # handel默认自父亲里面是空的 作用是什么?就是跟客户端所有操作,都是在handle里完成的,每个请求过来,都会走这里
while True:
try:
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0])) # 打印客户端的IP地址
print(self.data)
# if not self.data: # 客户端断开连接
# print(self.client_address,"断开连接!")
# break
self.request.send(self.data.upper())
except ConnectionResetError as error:
print("客户端已经断开连接!",error)
break
if __name__ == "__main__":
HOST, PORT = "HW-20180425SPSL", 6969 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
## client.py ## import socket
client = socket.socket() # 生命socket类型 同时 生成socket连接# 对相
client.connect(('HW-20180425SPSL',6969)) # 连接6969端口
while True:
msg = input(">>:").strip()
client.send(msg.encode("utf-8"))
data = client.recv(1024) #
print(data.decode()) client.close()
显示结果:
client.py

server.py

当客户端进行断开操作,那么服务端会出现什么情况呢?

SocketServer多并发操作
下面的程序是实现多用户在线Ftp程序
## client.py ## import socket
import os
import json class FtpClient(object):
def __init__(self):
self.client = socket.socket()
def help(self):
msg = '''
ls
pwd
cd ../..
get filename
put filename
'''
print(msg)
def connect(self,ip,port):
self.client.connect((ip, port))
def interactive(self):
#self.authenticate()
while True:
cmd = input(">>").strip()
if len(cmd) ==0:continue
cmd_str = cmd.split()[0]
if hasattr(self,"cmd_%s" % cmd_str):
func = getattr(self,"cmd_%s" % cmd_str)
func(cmd)
else:
self.help()
def cmd_put(self,*args):
cmd_split = args[0].split()
if len(cmd_split) > 1:
filename = cmd_split[1]
if os.path.isfile(filename):
filesize = os.stat(filename).st_size
msg_dic = {
"action": "put",
"filename":filename,
"size": filesize,
"overridden":True
}
self.client.send( json.dumps(msg_dic).encode("utf-8") )
print("send",json.dumps(msg_dic).encode("utf-8") )
#防止粘包,等服务器确认
server_response = self.client.recv(1024)
f = open(filename,"rb")
for line in f:
self.client.send(line)
else:
print("file upload success...")
f.close() else:
print(filename,"is not exist")
def cmd_get(self):
pass ftp = FtpClient()
ftp.connect('HW-20180425SPSL', 6969)
ftp.interactive()
## server.py ## import socketserver
import json
import os
class MyTCPHandler(socketserver.BaseRequestHandler): def put(self,*args):
'''接收客户端文件'''
cmd_dic = args[0]
filename = cmd_dic["filename"]
filesize = cmd_dic["size"]
if os.path.isfile(filename):
f = open(filename + ".new","wb")
else:
f = open(filename , "wb") self.request.send(b"200 ok")
received_size = 0
while received_size < filesize:
data = self.request.recv(1024)
f.write(data)
received_size += len(data)
else:
print("file [%s] has uploaded..." % filename) def handle(self):
while True:
try:
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
cmd_dic = json.loads(self.data.decode())
action = cmd_dic["action"]
if hasattr(self,action):
func = getattr(self,action)
func(cmd_dic) except ConnectionResetError as e:
print("err",e)
break
if __name__ == "__main__":
HOST, PORT = "HW-20180425SPSL", 6969
# Create the server, binding to localhost on port 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
结果显示:
client:

client(1):

server:

大聊Python----SocketServer的更多相关文章
- 大聊Python----协程
协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来 ...
- Python - 和我聊Python节目最新一期介绍 - 257期:使用超级电脑,Python,射电天文学知识来探索银河系
今天,给大家简单介绍和我聊Python的最新一期节目,第257期:使用超级电脑,Python,射电天文学知识来探索银河系. 听着标题就觉得高大上,是的,我也是这么认为的.这次请的嘉宾来头很大,来自国际 ...
- Python - 翻译Talk Python To Me (和我聊Python) 播客
“和我聊Python”是一个美国的聊天播客,英文名Talk Python To Me,类似于喜马拉雅的音频课程节目,只不过这个主题是编程语言Python.该节目从2015年的节目到现在,已经超过256 ...
- 让大蛇(Python)帮你找工作
前段时间用Python实现了一个网络爬虫(让大蛇(Python)帮你找工作),效率总体还可以,但是缺点就是每次都需要手动的去触发,于是打算对该爬虫加上Timer,经过网上一番搜索以及API的查询,发现 ...
- 使用Python SocketServer快速实现多线程网络服务器
Python SocketServer使用介绍 1.简介: SocketServer是python的一个网络服务器框架,可以减少开发人员编写网络服务器程序的工作量. SocketServer总共有4个 ...
- python从入门到大神---Python的jieba模块简介
python从入门到大神---Python的jieba模块简介 一.总结 一句话总结: jieba包是分词技术,也就是将一句话分成多个词,有多种分词模型可选 1.分词模块包一般有哪些分词模式(比如py ...
- 大爽Python入门教程 3-3 循环:`for`、`while`
大爽Python入门公开课教案 点击查看教程总目录 for循环 可迭代对象iterable 不同于其他语言. python的for循环只能用于遍历 可迭代对象iterable 的项. 即只支持以下语法 ...
- 大爽Python入门教程 3-4 实践例题
大爽Python入门公开课教案 点击查看教程总目录 1. 求和 使用循环,计算列表所有项的和,并输出这个和. 列表示例 lst = [8, 5, 7, 12, 19, 21, 10, 3, 2, 11 ...
- 大爽Python入门教程 3-5 习题
大爽Python入门公开课教案 点击查看教程总目录 1 求平方和 使用循环,计算列表所有项的平方和,并输出这个和. 列表示例 lst = [8, 5, 7, 12, 19, 21, 10, 3, 2, ...
- 大爽Python入门教程 3-6 答案
大爽Python入门公开课教案 点击查看教程总目录 1 求平方和 使用循环,计算列表所有项的平方和,并输出这个和. 列表示例 lst = [8, 5, 7, 12, 19, 21, 10, 3, 2, ...
随机推荐
- html中图片自适应浏览器和屏幕,宽度高度自适应
1.(宽度自适应):在网页代码的头部,加入一行viewport元标签. <meta name="viewport" content="width=device-wi ...
- centOS6.5如何从启动界面直接进入命令行界面
进入系统后,按Ctrl+Alt+Fn可以切换控制台,其中F1~F6是字符控制台,F7~F12是X控制台 如果启动直接进入字符控制台,而不是X Window,可以编辑/etc/inittab将id:5: ...
- ASP.NET MVC4计划任务实现方法(定时执行某个功能)
系统中定时执行某个任务是比较常用的功能,如一个部门定期向上级部门上报数据是一个典型的例子,下面就简单说说在.net mvc中如何实现定时执行某个功能的方法. 1.首先修改Glocal.asax文件,在 ...
- [洛谷P5166]xtq的口令
题目大意:给出一张有向图,保证任何时候边都是从编号大的向编号小连.两个操作: $1\;l\;r:$表示若编号在区间$[l,r]$内的点被染色了,问至少还需要染多少个点才可以使得整张图被染色.一个点会被 ...
- POJ3648:Wedding——题解(配2-SAT简易讲解)
http://poj.org/problem?id=3648 (在家,而且因为2-SAT写的不明不白的,所以这篇详细写) 题目大意: 有一对新人结婚,邀请了n-1 对夫妇去参加婚礼.婚礼上所有人要坐在 ...
- POJ2186:Popular Cows——题解
http://poj.org/problem?id=2186 题面纯英文--就不粘题面了. 简单的说,就是将图强连通分量缩点,然后拓扑一下. 为了避免拓扑,我们可以反向存图,然后查入度为0的点即可. ...
- HDU1281: 棋盘游戏(二分图匹配)
棋盘游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- google 浏览器的调试模式
1.电脑模式: 而在手机模式下的调试是:
- javascript常用实例的实现与封装
地址:https://github.com/chenhuiYj/ec-do 2.字符串操作 2-1去除字符串空格 //去除空格 type 1-所有空格 2-前后空格 3-前空格 4-后空格 fu ...
- sudo 的配置详解
从编写 sudo 配置文件/etc/sudoers开始: sudo的配置文件是/etc/sudoers ,我们可以用他的专用编辑工具visodu ,此工具的好处是在添加规则不太准确时,保存退出时会提示 ...