python中级第十二课--创建TCP服务器(二)(小白piao分享)

接上回内容:

        在上一回中,我们提到,多线程服务器(ThreadingTCPServer)的创建,有一个问题,多线程服务器那样设计允许连接的客户端是没有上限的,因此一个黑客可能利用海量数据模拟客户端登录,登录你的服务器导致你的服务器挂死,如果考虑这个问题,我们应该为服务器添加线程个数限制,即创建一个工作者线程或者进程池。
        要做到这一点,我们首先创建一个普通的单线程服务器,然后在多个线程中调用server_forever()方法。例子:

from socketserver import TCPServer,StreamRequestHandler

class server_request_handler(StreamRequestHandler):
    def handle(self):#注意:这个函数不能重命名,是重写了父类的handle函数,并且会在服务器连接到客户端时自动调用
        print('GOT a CONNECTION:',self.client_address)
        while True:
            msg = self.request.recv(8192)
            if not msg:
                break
            self.request.send(msg)

if __name__ == '__main__':
    from threading import Thread
    NWORKERS = 32
    serv = TCPServer(('',20000),server_request_handler)
    for n in range(NWORKERS):
        t = Thread(target=serv.serve_forever)#线程处理函数直接是服务启动函数即可
        t.daemon = True# 事件激活
        t.start()
    serv.serve_forever()

#如上代码中使用了StreamRequestHandler,比起BaseRequestHandler要更加灵活。

        也可以详细设置服务器属性:

if __name__ == '__main__':
    from threading import Thread
    import socket
    NWORKERS = 32
    print(NWORKERS)
    serv = TCPServer(('',20000),server_request_handler,bind_and_activate=False)
    print(serv)
    serv.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)# setsockopt(level, optname, value)
    serv.server_bind()# 绑定端口
    serv.server_activate()#监听(激活)
    for n in range(NWORKERS):
        t = Thread(target=serv.serve_forever)#线程处理函数直接是服务启动函数即可
        t.daemon = True
        t.start()
    serv.serve_forever()

        同样,所有的高级网络模块(HTTP,XML-RPC)都是在socketserver的功能上构建的,换句话说,直接使用socket库来实现服务器也不困难:

import socket

def echo_handler(address, client_sock):
    print('GOT a connection:',address,'client_socket:',client_sock)
    while True:
        msg = client_sock.recv(8192)
        if not msg:
            break
        client_sock.sendall(msg)
    client_sock.close()

def echo_server(address,backlog=5):
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.bind(address=address)# 绑定
    sock.listen(backlog=backlog)# 监听
    while True:
        client_sock,client_addr = sock.accept()#接收客户端
        echo_handler(client_addr, client_sock)# 服务器处理客户端申请

if __name__ == '__main__':
    echo_server(('',20000))

        以上,就为服务器的创建,但是服务器处理客户端的流程(例如:server_request_handler、echo_handler)需要自定义设置,要更加灵活,还有多数情况会结合多线程去开发一个多线程服务器,以上的例子很充分地体现了这些需求,大家可以花点时间消化吸收

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白piao

创作不易,支持一下!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值