大聊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, ...
随机推荐
- CentOS 6安装thrift支持erlang开发
早前,在我的博文thrift多平台安装介绍了如何在debian/ubuntu下面安装thrift,并支持erlang开发的.而在CentOS平台下,并没有成功安装.经过不断摸索,终于成功了,这篇博文就 ...
- HBase 所有命令解析
COMMAND GROUPS:Group name: generalCommands: status, table_help, version, whoami Group name: ddlComma ...
- matlab如何将数组中的NAN值去除
比如我们一组数据,里面有不少的NaN值,如何将其删除掉呢?可以通过find函数来搞定. 我们可以通过importdata('data.txt')将数据文件data.txt导入数组A中. ...
- change object keys & UpperCase & LowerCase
change object keys & UpperCase & LowerCase .toLocaleUpperCase(); && .toLocaleLowerCa ...
- Delphi 的绘图功能[8] - TextOut、TextWidth、TextHeight
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...
- Devc++编译系统分配给int多少字节
我看的是<C语言程序设计>..谭浩强的PDF版 里面只讲了VC和TC 的,没有Devc++的..(我的是5.10版) 还有这是什么意思? 经过查阅我进行了这样的测试: 得到了这样的结果: ...
- [CF888G]Xor-MST
题目大意:给一个$n$个点的完全图,第$i$个点有点权$v_i$,一条边$x-y$的边权为$v_x\oplus v_y$,求最小生成树 题解:明显$Kruskal$和$Prim$都会$TLE$,有一种 ...
- POJ3422:Kaka's Matrix Travels——题解
http://poj.org/problem?id=3422 题目大意: 从左上角走到右下角,中途取数(数>=0),然后该点的数变为0,求走k的总价值和最大值. ———————————————— ...
- HDU.1596 find the safest road (Floyd)
HDU.1596 find the safest road (Floyd) 题意分析 与普通的最短路不太相同,本题有些许的变化. 1. 要找到由i到j最安全的路,故在求解的时候要保证mp[i][j]尽 ...
- HDOJ.1228 A + B (map)
A + B 点我挑战题目 点我一起学习STL-MAP 题意分析 讲字符串和数字用map对应即可 代码总览 /* Title:HDOJ.1228 Author:pengwill Date:2016-11 ...