文档章节

实现简单的服务器

mickelfeng
 mickelfeng
发布于 2017/05/24 22:52
字数 2407
阅读 34
收藏 0

 前言

SocketServer是标准库中一个高级别的模块,用于简化网络客户与服务器的实现。模块中,已经实现了一些可供使用的类。

    该模块是一个简单的网络服务器模块。它由四个基本的服务器类组成:TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer。这四个类都是同步请求,只有一个请求完全处理完成后,下一个请求才会被处理,这样的模式不适合每个请求要花费很长时间的情况。该方法为每个请求生成单独的进程或者线程,ForkingMixInThreadingMixIn类可以提供异步的处理框架。来自  other

在Python3中,本模块为socketserver模块。在Python 2中,本模块为SocketServer模块。所以在用import导入时,要分情况导入,否则会报错。导入的代码如下:

try:
    import socketserver      #Python 3
except ImportError:
    import SocketServer      #Python 2

SocketSerror模块包括许多可以简化TCP、UDP、UNIX域套接字  服务器实现的类。

一、处理程序

要使用本模块,必须定义一个继承于基类BaseRequestHandler的处理程序类。BaseRequestHandler类的实例h可以实现以下方法:

1、h.handle()  调用该方法执行实际的请求操作。调用该函数可以不带任何参数,但是几个实例变量包含有用的值。h.request包含请求,h.client_address包含客户端地址,h.server包含调用处理程序的实例。对于TCP之类的数据流服务,h.request属性是套接字对象对于数据报服务,它是包含收到数据的字节字符串。

2、h.setup()   该方法在handle()之前调用。默认情况下,它不执行任何操作。如果希望服务器实现更多连接设置(如建立SSL连接),可以在这里实现。

3、h.finish()   调用本方法可以在执行完handle()之后执行清除操作。默认情况下,它不执行任何操作。如果setup()和handle()方法都不生成异常,则无需调用该方法。

             如果知道应用程序只能操纵面向数据流的连接(如TCP),那么应从StreamRequestHandler继承,而不是BaseRequestHandler。StreamRequestHandler类设置了两个属性,h.wfile是将数据写入客户端的类文件对象,h.rfile是从客户端读取数据的类文件对象。

          如果要编写针对数据包操作的处理程序并将响应持续返回发送方,那么它应当从DatagramRequestHandler继承。它提供的类接口与StramRequestHandler相同。

二、服务器

       要使用处理程序,必须将其插入到服务器对象。定义了四个基本的服务器类。

      (1)TCPServer(address,handler)   支持使用IPv4的TCP协议的服务器,address是一个(host,port)元组。Handler是BaseRequestHandler或StreamRequestHandler类的子类的实例。

      (2)UDPServer(address,handler)   支持使用IPv4的UDP协议的服务器,address和handler与TCPServer中类似。

      (3)UnixStreamServer(address,handler)   使用UNIX域套接字实现面向数据流协议的服务器,继承自TCPServer。

      (4)UnixDatagramServer(address,handler)  使用UNIX域套接字实现数据报协议的服务器,继承自UDPServer。

所有四个服务器类的实例都有以下方法和变量:

1、s.socket   用于传入请求的套接字对象。

2、s.sever_address  监听服务器的地址。如元组("127.0.0.1",80)

3、s.RequestHandlerClass   传递给服务器构造函数并由用户提供的请求处理程序类。

4、s.serve_forever()  处理无限的请求

5、s.shutdown()   停止serve_forever()循环

6、s.fileno()   返回服务器套接字的整数文件描述符。该方法可以有效地通过轮询操作(如select()函数)使用服务器实例。

三、定义自定义服务器

服务器往往需要特殊的配置来处理不同的网络地址族、超时期、并发和其他功能,可以通过继承上面四个基本服务器类来自行定义。

    可以通过混合类获得更多服务器功能,这也是通过进程或线程分支添加并发行的方法。为了实现并发性,定义了以下类:

(1)ForkingMixIn         将UNIX进程分支添加到服务器的混合方法,使用该方法可以让服务器服务多个客户。

(2)ThreadingMixIn    修改服务器的混合类,可以使用线程服务多个客户端。

要向服务器添加这些功能,可以使用多重继承,其中首先列出混了类。

由于并发服务器很常用,为了定义它,SocketServer预定义了以下服务器类:

(1)ForkingUDPServer(address,handler)   

(2)ForkingTCPServer(address,handler)

(3)ThreadingUDPServer(address,handler)

(4)ThreadingTCPServer(address,handler)

 

上面有点乱,现总结以下:

SocketServer模块中的类主要有以下几个:

1、BaseServer    包含服务器的核心功能与混合类(mix-in)的钩子功能。这个类主要用于派生,不要直接生成这个类的类对象,可以考虑使用TCPServer和UDPServer类。

2、TCPServer    基本的网络同步TCP服务器

3、UDPServer    基本的网络同步UDP服务器

4、ForkingMixIn   实现了核心的进程化功能,用于与服务器类进行混合(mix-in),以提供一些异步特性。不要直接生成这个类的对象。

5、ThreadingMixIn   实现了核心的线程化功能,用于与服务器类进行混合(mix-in),以提供一些异步特性。不要直接生成这个类的对象。

6、ForkingTCPServer     ForkingMixIn与TCPServer的组合

7、ForkingUDPServer    ForkingMixIn与UDPServer的组合

8、BaseRequestHandler

9、StreamRequestHandler    TCP请求处理类的一个实现

10、DataStreamRequestHandler   UDP请求处理类的一个实现

 

现在繁杂的事务都已经封装到类中了,直接使用类即可。

使用SocketServer模块编写的TCP服务器端代码:

#! /usr/bin/env python
#coding=utf-8
"""使用SocketServer来实现简单的TCP服务器"""
from SocketServer import (TCPServer,StreamRequestHandler  as SRH)
from time import ctime

class MyRequestHandler(SRH):
    def handle(self):
        print "connected from ",self.client_address
        self.wfile.write("[%s] %s"  %(ctime(),self.rfile.readline()))

tcpSer=TCPServer(("",10001),MyRequestHandler)
print "waiting for connection"
tcpSer.serve_forever()

 

 相应的TCP客户端代码:

#! /usr/bin/env python
#coding=utf-8
from socket import *
BUFSIZE=1024
#每次都要创建新的连接
while True:
    tcpClient=socket(AF_INET,SOCK_STREAM)
    tcpClient.connect(("localhost",10001))
    data=raw_input(">")
    if not data:
        break
    tcpClient.send("%s\r\n" %data)
    data1=tcpClient.recv(BUFSIZE)
    if not data1:
        break
    print data1.strip()
    tcpClient.close()

 

 

Python实现简单的HTTP服务器

用于搭建http server的模块有如下三种:
1)BaseHTTPServer:提供基本的Web服务和处理器类,分别是HTTPServer及BaseHTTPRequestHandler;
2)SimpleHTTPServer:包含执行GET和HEAD请求的SimpleHTTPRequestHandler类;
3)CGIHTTPServer:包含处理POST请求和执行的CGIHTTPRequestHandler类。
在我目前的实现中,主要采用BaseHTTPServer模块。

一、 BaseHTTPServer模块

HTTPServer是一个SocketServer.TCPServer的子集,创建并监听HTTP套接字,分配requests到处理器(handler), BaseHTTPRequestHandler在HTTP请求到达时进行处理,但其自身并不能对请求作出相应,由另一个派生类来处理每一个请求方法。BaseHTTPRequestHandler为子集提供许多类变量、实例变量和方法,其分析请求对象和请求头部,并根据请求类型调用相应的方法。一般这个模块不被直接使用,而是被用来作为构建功能性Web服务器的一个基类。

BaseHTTPRequestHandler其中的实例变量有:

1)client_address 包含关联的客户端地址(host, port)

2)command 包含请求类型(eg: get )

3)path 包含的请求路径

4)request_version 包含请求版本的字符串(eg: 'HTTP/1.0')

5)headers

6)rfile 输入流

7)wfile 包含写到客户端响应的输出流

BaseHTTPRequestHandler的类变量有:

1)server_version 指定服务器软件版本

2)sys_version Python系统版本

3)error_message_format

4)protocol_version 响应中使用的HTTP协议版本

BaseHTTPRequestHandler部分操作

1)handle()

2)send_error(code[, message]) 发送并记录一个完整的错误回复到客户端

3)send_response(code[, message]) 发送一个响应头并记录已接收的请求

4)send_header(keyword, value) 编写一个指定的HTTP头到输出流

5)version_string() 饭后服务器软件的版本字符串

日志记录相关部分没有一一列出。。。。

二、简单创建server实例

以下是一个简单的创建http server的例子,网上有些是采用多线程实现的比较复杂的例子

1. 创建server

    1)DOS 命令
          在DOS里cd到准备做服务器根目录的路径下,运行命令
          python -m BaseHTTPServer [port]
          默认的端口号是8000, 服务器根目录就是运行python命令的工作目录,server创建好后默认启动成功
    2)Python脚本启动

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler  
class TestHTTPHandle(BaseHTTPRequestHandler):  
    def do_GET(self):  
  
        buf = "It works"  
        self.protocal_version = "HTTP/1.1"   
  
        self.send_response(200)  
  
        self.send_header("Welcome", "Contect")         
  
        self.end_headers()  
  
        self.wfile.write(buf)  
  
def start_server(port):  
    http_server = HTTPServer(('[IP]', int(port)), TestHTTPHandler)  
    http_server.serve_forever() #设置一直监听并接收请求  

其中,IP为给localhost设定的访问地址  

2. 浏览器访问

    服务器开启后,就可以通过浏览器输入网址访问服务器资源
          http://localhost:port/directory
    如在主路径下准备好info.xml文件后,可通过在浏览器输入http://localhost:1000/info.xml进行访问

3. 服务器关闭

    1) dos

          在运行界面中输入 "ctrl + C" 停止

    2)python脚本

         需停止端口监听及相关python进程

      def stop_server(server)

          server.sorket.close()

 

实现SimpleHTTPServer的POST方法

import SimpleHTTPServer
import SocketServer
import re

def htc(m):
    return chr(int(m.group(1),16))

def urldecode(url):
    rex=re.compile('%([0-9a-hA-H][0-9a-hA-H])',re.M)
    return rex.sub(htc,url)

class SETHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def createHTML(self):
        html = file("index.html", "r")
        for line in html:
            self.wfile.write(line)
            
    def do_GET(self):
        print "GET"
        print self.headers;
        self.createHTML()
        
    def do_POST(self):
        print "POST"
        print self.headers;
        length = int(self.headers.getheader('content-length'))
        qs = self.rfile.read(length)
        url=urldecode(qs)
        print "url="
        print url
        self.createHTML()
        
Handler = SETHandler
PORT = 8000
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()

 

本文转载自:http://blog.csdn.net/linda1000/article/details/8087546

mickelfeng

mickelfeng

粉丝 234
博文 2769
码字总数 597345
作品 0
成都
高级程序员
私信 提问
Java Socket框架Apache MINA:实现Socket服务器端

版权声明:本文为Zhang Phil原创文章,请不要转载! https://blog.csdn.net/zhangphil/article/details/88247632 Java Socket框架Apache MINA:实现Socket服务器端 现在用Apache MINA实现一个...

zhangphil
03/27
0
0
(转) Twisted : 第十二部分 改进诗歌下载服务器

新的服务器实现 这里我们要新写一个Twisted版的服务器。然后,再来讨论一些Deferred的新功能。 在第九、十部分,我们提出了诗歌转换引擎这个概念。由于其实现太过简单,因此我们用随机选择来...

水果糖
2016/01/27
12
0
C实现WEB服务器端的通信接收

本文是《Mina 实现自定义协议的通信》服务器端的解释和扩充。 服务器端代码在不使用第三方开源或者商业的代码库前提下,通过C语言自定义实现了WEB服务器端的数据接收和通信。可以简单的理解为...

ppdep
2012/10/31
0
9
Python3简单使用xmlrpc实现RPC

RPC 先说说什么是RPC,RPC(Remote Procedure Call)——远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如T...

Cloudox_
2017/12/25
0
0
AeroFS 开源 SSMP 协议,包含 Java 和 Go 实现

AeroFS 团队今天开源了 SSMP 协议,SSMP 也就是 Stupid-Simple Messaging Protocol,里面包含协议规范,Go 实现,Java 实现和服务器加载测试工具。 XMPP 历史 XMPP 在 AeroFS 有一段很长的历...

oschina
2015/09/11
3K
6

没有更多内容

加载失败,请刷新页面

加载更多

【AI实战】手把手教你深度学习文字识别(文字检测篇:基于MSER, CTPN, SegLink, EAST等方法)

文字检测是文字识别过程中的一个非常重要的环节,文字检测的主要目标是将图片中的文字区域位置检测出来,以便于进行后面的文字识别,只有找到了文本所在区域,才能对其内容进行识别。 文字检...

雪饼
今天
5
0
思维导图XMind 8 Pro 绿化方法(附序列号)

按部就班: Step 1 -全新下载最新版本的 Xmind 8(注必须是英文官方的版本,中文代{过}{滤}理网站的版本修改过,无法使用pj); Step 2 -安装完毕后,点击文末的下载按钮下载pj补丁文件包,将...

一只小青蛙
今天
10
0
数据结构(ER数据库)设计规范

表命名规范 表命名的规则分为3个层级,层级之间通过_分割,例如b_r_identity、d_l_identity。规约为: [leavel]_[type]_[name] [leavel] 表示数据库表的层级和功能,分为: s:业务无关的系统...

随风溜达的向日葵
今天
5
0
阿里Sentinel控制台源码修改-对接Apollo规则持久化

https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel 动态规则扩展 https://github.com/alibaba/Sentinel/wiki......

jxlgzwh
昨天
7
0
在Linux系统中创建SSH服务器别名

如果你经常通过 SSH 访问许多不同的远程系统,这个技巧将为你节省一些时间。你可以通过 SSH 为频繁访问的系统创建 SSH 别名,这样你就不必记住所有不同的用户名、主机名、SSH 端口号和 IP 地...

老孟的Linux私房菜
昨天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部