python3 用socketserver框架建立TCP,UDP服务器

python 中采用 socketserver模块可以更方便地建立TCP,UDP服务器。


1.socketserver模块

2.步骤及代码

3.socketserver框架实现多线程服务器


1.socketserver模块

socketserver是python 的一个网络服务器框架,可以减少编写网络服务器程序的工作量。

socketserver模块只能用来写服务端

socketserver模块中使用的服务器类主要有 : TCPserverUDPserverThreadingTCPserverThreadingUDPserverForkingTCPserverForkingUDPserver

有TCP字段的表示TCP协议服务器,有UDP字段的表示UDP协议服务器,有Threading字段的表示多线程,有Forking字段的表示多进程

socketserver模块中使用的处理器类主要有 : StreamRequestHandler(基于TCP协议) , DatagramRequestHandler(基于UDP协议)。处理器类中有一个十分重要的方法:handler() 。 处理器类用来做什么操作都是写在handler()里的

class myTcp(socketserver.StreamRequestHandler):    #继承TCP的处理器类
    def handle(self):
       xxx   #myTcp这个类要做的操作写在handler()里

工作模式:

socketserver 框架 分为两大类操作,一是 服务器类(就是上面的TCPserver,UDPserver等等),二是处理器类处理器类用于处理数据接收或者传送,而服务器类用于处理客户端和服务端通信问题

只要继承其中一个处理器类(TCP 或 UDP),就可以自定义一个处理器类(自定义数据如何传送或接收)


2.步骤及代码

1.选择一个服务器类,并创建其对象(如对象叫 server)。

2.自定义处理器类(或叫请求类)的功能

3.调用对象(server)的serve_forever() 方法 来 启动服务器


基于socketserver 的TCP服务端

from socketserver import StreamRequestHandler as Tcp     #选择 TCP的处理器类
import socketserver
host=''
port = 8888
addr = (host,port)

'''处理器类部分'''
class myTcp(Tcp):                                   #第二步:自定义处理器类的功能(这也是一个请求--request)
    def handle(self):
        print('client\'s address:',self.client_address),    #打印连接上的客户端的 ip地址
        while True:
            data = self.request.recv(1024)                      #从客户端接收信息
            if not data:
                break
            print(data.decode('utf-8'))
            self.request.sendall(data)                          #向客户端发送信息

if __name__ == '__main__':
    '''服务器类部分'''
    server = socketserver.TCPServer(addr,myTcp)     #第一步:.选择一个服务器类,并创建其对象
    server.serve_forever()                          #第三步:开启服务器

客户端代码:

from socket import *

host ='localhost'	#我是本机操作,所以host写localhost,如果是连接外部的服务器,host就要等于服务器的ip地址
port =8888
bufsize = 1024
addr = (host,port)
client = socket(AF_INET,SOCK_STREAM)
client.connect(addr)
while True:
    data = input()
    if not data or data=='exit':
        break
    client.send(data.encode('utf-8'))
    data = client.recv(bufsize)
    if not data:
        break
    print (data.decode('utf-8'))
client.close()



基于 socketserver 的 UDP服务端代码:

from socketserver import DatagramRequestHandler as udp     #选择 UDP的处理器类
import socketserver
host=''
port = 8888
addr = (host,port)

'''处理器类部分'''
class myUDP(udp):                                   #第二步:自定义处理器类的功能(这也是一个请求--request)
    def handle(self):
        print('client\'s address:',self.client_address),    #打印连接上的客户端的 ip地址
        while True:
            data = self.rfile.readline()                #读取客户端发来的信息
            if not data:
                break
            print(data.decode('utf-8'))
            self.wfile.write(data)                       #向客户端发送信息

if __name__ == '__main__':
    '''服务器类部分'''
    server = socketserver.UDPServer(addr,myUDP)     #第一步:.选择一个服务器类,并创建其对象
    server.serve_forever()                          #第三步:开启服务器


UDP客户端:

from socket import *

host ='localhost'
port =8888
bufsize = 1024
addr = (host,port)
client = socket(AF_INET,SOCK_DGRAM)

while True:
    data = input()
    if not data or data=='exit':
        break
    client.sendto(data.encode('utf-8'),addr)
    data,saddr= client.recvfrom(bufsize)
    if not data:
        break
    print (data.decode('utf-8'))
client.close()



3.用socketserver框架实现多线程服务器


Threading.TCPServer(服务类)  +  StreamRequesetHandler(处理类或叫请求类)  =  TCP多线程服务器

多线程 TCP 服务端:

from socketserver import ThreadingTCPServer, StreamRequestHandler

class myTCP(StreamRequestHandler):  
    def handle(self):  
        while True:
            data = self.request.recv(1024)
            print ("receive from (%r):%r" % (self.client_address, data))
            self.wfile.write(data)
  
if __name__ == "__main__":  
    host = ""       #主机名,可以是ip,像localhost的主机名,或""  
    port =8888     #端口
    addr = (host, port)  
      
    server = ThreadingTCPServer(addr, myTCP)   #实例化一个 多线程TCP服务类
    server.serve_forever()                     #开启
上面的代码运行后,就可以接受多个客户端发来的连接和信息。(客户端代码可以用 TCP客户端代码,文章有)


上面的代码还是有缺憾的,就是这个程序就只能运行一个多线程TCP。

下面我们试试,一个程序除了运行 一个多线程TCP外,还可以用其他多线程运行其他任务(如:计数任务)


[ 一个程序运行 多个不同功能的线程 ]

from socketserver import ThreadingTCPServer, StreamRequestHandler
import  socketserver
import threading
import time

'''线程任务1'''
class myTCP(StreamRequestHandler):  #TCP处理器类(或叫请求类) 在这里 作为一个 线程任务
    def handle(self):  
        while True:
            data = self.request.recv(1024)
            print ("receive from (%r):%r" % (self.client_address, data))
            self.wfile.write(data)

'''线程任务2'''
class Count(threading.Thread):        #另一个线程任务,用于计数,暂且叫他计数线程
    count = 0
    def run(self):
        while True:
            self.count += 1
            print('count = ',self.count)
            time.sleep(1)

if __name__ == "__main__":  
    host = ""
    port =8888
    addr = (host, port)  

    '''实现一个多线程TCP服务器'''
    server = ThreadingTCPServer(addr,myTCP)                  #实例化一个多线程TCP服务器类
    server_thread = threading.Thread(target=server.serve_forever)   #创建线程,线程用于TCP多线程
    server_thread.start()                                           #开启线程

    '''实现循环计数'''
    count_thread = Count()                      #创建计数线程
    count_thread.start()                        #开启线程


  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值