热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

02:SocketServer服务

网络编程其他篇目录:1.1SocketServer四种基本流及异步处理理论部分1.2创建socketserver实现:多客户端并发1.3SocketServer实现多

网络编程其他篇

目录:

  • 1.1 SocketServer四种基本流及 异步处理理论部分
  • 1.2 创建socketserver实现: 多客户端并发
  • 1.3 SocketServer实现多并发FTP 部分功能

1.1 SocketServer四种基本流及 异步处理理论部分     返回顶部

  1、SocketServer作用

      1.  socket无法支持多并发,SocketServer 可以实现多并发

      2.  SocketServer使编写一个Socket服务器通信变得更加简单

      3.  SocketServer其实就是对socket的再封装

  2、SocketServer提供了4个基本的服务类

      1. TCPServer针对TCP套接字流
      2. UDPServer针对UDP数据报套接字
      3. UnixStreamServer和UnixDatagramServer针对UNIX域套接字,不常用(Unix本机间通信)
      4. 它们的继承关系如下:

                           

   3、异步处理

      1.  上面四个服务类都是同步处理请求的,一个请求没处理完不能处理下一个请求

      2.  要想支持异步模型,可以利用多继承让server类继承ForkingMixInThreadingMixIn mix-in classes。

      3.  ForkingMixIn利用多进程(分叉)实现异步。

      4.  ThreadingMixIn利用多线程实现异步。

  4.、请求处理类

      1.  要实现一项服务,还必须派生一个handler class请求处理类,并重写父类的handle()方法

      2.  handle方法就是用来专门是处理请求的,该模块是通过服务类和请求处理类组合来处理请求的。

      3.  SocketServer模块提供的请求处理类有BaseRequestHandler,以及它的派生类StreamRequestHandler和DatagramRequestHandler

      4.  从名字看出可以一个处理流式套接字,一个处理数据报套接字。

  5、实现异步,支持多连接

      1.  前面介绍服务类时提到过,四个基本的服务类默认是同步模型的。

      2.  要想支持异步可以利用多继承从ForkingMixInThreadingMixInmix-in classes和一个基本的服务类继承来定义一个支持异步的服务类

      3.  比如:class Server(ThreadingMixIn, TCPServer): pass

      4.  ForkingMixIn 要考虑进程间的通信。ThreadingMixIn要考虑线程访问同一变量时的同步和互斥

1.2 创建socketserver实现: 多客户端并发     返回顶部

  1、创建一个socketserver 至少分以下几步

      1.  创建一个request handler class(请求处理类),继承自BaseRequestHandler class并重写它的handle()方法,该方法将处理客户端的请求。

      2.  实例化一个server class对象,并将服务的地址和之前创建的request handler class传递给它。

           server class对象有这些:TCPServer;UDPServer;UnixStreamServer;UnixDatagramServer

      3.  调用server class对象的handle_request() 或 serve_forever()方法来开始处理请求

      4.  handle_request和server_forever区别是server_forever只是反复handle_request而已

import socketserver
class MyTcpServer(socketserver.BaseRequestHandler):def handle(self):while True:self.request.recv(1024)self.request.send('I am server'.encode('utf-8'))
server
= socketserver.ThreadingTCPServer(('127.0.0.1',8888),MyTcpServer)
server.serve_forever()

简化版的server端代码如下

import socketserver
#每个客户端过来都会实例化一个MyTCPHandler实例,并调用handle方法来处理与客户端的通信
class MyTCPHandler(socketserver.BaseRequestHandler):
#1 第一步:创建一个request handler class(请求处理类),继承自BaseRequestHandler classdef handle(self): #2 第二步:并重写它的handle()方法,该方法将处理客户端的请求while True:try:self.data = self.request.recv(1024).strip() #conn.recv(1024) = self.request.recv()print("{} wrote:".format(self.client_address[0]))print(self.data)self.request.send(self.data.upper()) #conn.send()=self.request.sendall()except ConnectionResetError as e:print("error",e)break
if __name__ == "__main__":HOST, PORT = "localhost", 9999server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) #socketserver.TCPServer(单)server.serve_forever() #4 第四步:调用server class对象的serve_forever()方法来开始处理请求
#
3 第三步:实例化一个server class对象,并将服务的地址和之前创建的request handler class传递给它
#
注: 实例化一个server class对象工作原理
#
a. (HOST, PORT):将监听地址当做一个参数传递给socketserver.TCPServer()
#
b. 每连接一个客户端就用MyTCPHandler实例化一个对象,将实例对象传送给socketserver.TCPServer
#
c. 然后服务器端使用MyTCPHandler类中的handle方法与客户端通信

socketserver实现多客户端并发: server端

import socket
client
= socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('localhost',9999)) #指定要连接的服务器地址和端口号
while True:msg = input(">>:").strip() #输入要发送给服务器的消息if len(msg) == 0:continue #如果客户端输入空格,让客户端继续输入client.send(msg.encode("utf-8")) #将输入的消息发送到服务器端data = client.recv(1024) #接收服务器端发送过来的数据,每次1024字节print('client_recv:',data) #将从服务器端接收的数据在客户端打印出来
client.close()

socketserver实现多客户端并发: client端

1.3 SocketServer实现多并发FTP 部分功能     返回顶部

  1、使用SocketServer完成FTP的多用户上传这个步骤

import socketserver,os,json #服务器端代码
class MyTCPHandler(socketserver.BaseRequestHandler):def put(self,*args):&#39;&#39;&#39;接收客户端文件&#39;&#39;&#39;cmd_dic &#61; args[0]filename &#61; cmd_dic["filename"]filesize &#61; cmd_dic["size"]if os.path.isfile(filename):f &#61; open(filename &#43; &#39;.new&#39;,&#39;wb&#39;)else:f &#61; open(filename,&#39;wb&#39;)print("file not exist",filename)self.request.send(b"200 ok")receive_size &#61; 0while receive_size < filesize:data &#61; self.request.recv(1024)f.write(data)receive_size &#43;&#61; len(data)else:print("file [%s] hsa uploaded ..."%filename)def handle(self):while True:try:self.data &#61; self.request.recv(1024).strip()print("{} wrote:".format(self.client_address[0]))print(self.data)cmd_dic &#61; json.loads(self.data.decode())action &#61; cmd_dic["action"]if hasattr(self,action):func &#61; getattr(self,action)func(cmd_dic)except ConnectionResetError as e:print("error",e)break
if __name__ &#61;&#61; "__main__":HOST, PORT &#61; "0.0.0.0", 9999server &#61; socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)server.serve_forever()

多用户上传: server端代码

import socket,os,json
class FtpClient(object):def __init__(self):self.client &#61; socket.socket()def help(self):msg &#61; &#39;&#39;&#39;ls; pwd; cd .. ;get filename ; put filename&#39;&#39;&#39;print(msg)def connect(self,ip,port):self.client.connect((ip,port))def interactive(self):#self.authenticate()while True:cmd &#61; input(">>:").strip()if len(cmd) &#61;&#61; 0:continuecmd_str &#61; cmd.split()[0]if hasattr(self,&#39;cmd_%s&#39;%cmd_str):func &#61; getattr(self,&#39;cmd_%s&#39;%cmd_str)func(cmd)else:self.help()def cmd_put(self,*args):cmd_split &#61; args[0].split()if len(cmd_split) > 1:filename &#61; cmd_split[1]if os.path.isfile(filename):filesize &#61; os.stat(filename).st_sizemsg_dic &#61; {"action": "put","filename":filename,&#39;size&#39;:filesize,&#39;overridden&#39;:True}self.client.send( json.dumps(msg_dic).encode(&#39;utf-8&#39;) )server_response &#61; self.client.recv(1024) #防止连包&#xff0c; 等服务器确认f &#61; open(filename,&#39;rb&#39;)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
&#61; FtpClient()
ftp.connect(
"1.1.1.3",9999)
ftp.interactive()

多用户上传: client端代码

1、将server端代码复制到Linux下&#xff0c;路径&#xff1a;/bbb/server.py
2. 将client端代码直接放到PyCharm中运行
3. 在PyCharm中执行put tt.py将本目录下的tt.py文件上传到linux的/bbb文件夹中>>:put tt.pyfile upload success.....
4. 执行命令完成后就可以看到有这个文件&#xff1a;/bbb/tt.py

用户上传运行演示

  2、文件传输时显示进度条

import sys,time
def view_bar(num, total):rate &#61; num / totalrate_num &#61; int(rate * 100)r &#61; &#39;\r[%s%s]%d%%&#39; % ("&#61;"*num, " "*(100-num), rate_num, )sys.stdout.write(r)sys.stdout.flush()for i in range(0, 101):time.sleep(0.1)view_bar(i, 100)# 1&#xff09;这里使用的是sys.stdout.write(r)&#xff0c;输出结果是进度条增加&#xff0c;但是不会换行
#
2&#xff09;2.x中的print无法指定end符号为其他值&#xff0c;默认会输出一个"\n"&#xff0c;也就是用一次必定换到下一行
#
3&#xff09;到了3.x中print成为了一个真正意义上的函数&#xff0c;后来就可以任意指定end符号的值&#xff0c;你可以输出一次后末尾添加上任意你想要的值&#xff0c;而不是强制换行。
#
4&#xff09;stdout没有end这个符号这一说&#xff0c;输出不会换行&#xff0c;因此如果你想同一样输出多次&#xff0c;在需要输出的字符串对象里面加上"\r",就可以回到行首了。

打印进度条代码

 

转:https://www.cnblogs.com/xiaonq/p/7904277.html



推荐阅读
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • Python实现变声器功能(萝莉音御姐音)的方法及步骤
    本文介绍了使用Python实现变声器功能(萝莉音御姐音)的方法及步骤。首先登录百度AL开发平台,选择语音合成,创建应用并填写应用信息,获取Appid、API Key和Secret Key。然后安装pythonsdk,可以通过pip install baidu-aip或python setup.py install进行安装。最后,书写代码实现变声器功能,使用AipSpeech库进行语音合成,可以设置音量等参数。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • UDP千兆以太网FPGA_verilog实现(四、代码前期准备UDP和IP协议构建)
    UDP:userDatagramprotocol用户数据报协议无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETFRFC76 ... [详细]
  • SQL Server 2008 到底需要使用哪些端口?
    SQLServer2008到底需要使用哪些端口?-下面就来介绍下SQLServer2008中使用的端口有哪些:  首先,最常用最常见的就是1433端口。这个是数据库引擎的端口,如果 ... [详细]
author-avatar
秀珍冠秋晓雯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有