Python 标准类库 - 因特网协议与支持之socketserver

简介: Python 标准类库 - 因特网协议与支持之socketserver

标准类库 - 因特网协议与支持之socketserver

by:授客 QQ1033553122

socketserver 模块,简化网络服务编写任务。

 

创建服务的步骤

1  通过子类化BaseRequestHandler 类,创建一个请求处理程序,并且重写handle()方法,该方法将处理接收到的请求

2 传递服务器地址和请求处理程序类参数,实例化server类(如TCPServer)

3 调用server对象的handle_request()、serve_forever()方法,处理单个、多个请求

 

实例

socketserver.TCPServer

服务端(单线程服务器)

#!/usr/bin/env python 3.4.0

#-*- encoding:utf-8 -*-

 

__author__ = 'shouke'

 

import socketserver

 

class MyTCPHandler(socketserver.BaseRequestHandler):

   """

   server使用的RequestHandler.

 

   每个客户端连接连接到服务器时都会被初始化一次,并且必须重写handle()方法以便同客户端交流。

   """

 

   def handle(self):

       while True:

           # self.request即为与客户端连接的TCP socker

           self.data = self.request.recv(1024).decode('utf-8').strip()

           print('receive data from client[host%s port%s]%s' % (self.client_address[0], self.client_address[1], self.data))

           if self.data == 'bye':

               self.request.sendall(bytes('bye', encoding='utf-8'))

               self.request.close()

               break

           else:

               self.request.sendall(self.data.upper().encode('utf-8'))

 

if __name__ == '__main__':

   # 创建TCPSocket服务器,绑定到10.118.52.26地址上,端口8000

   server = socketserver.TCPServer(('10.118.52.26', 8000), MyTCPHandler)

 

   # 激活服务器,让服务器一直运行,直到按Ctrl+C

   server.serve_forever()

 

 

客户端

#!/usr/bin/env python 3.4.0

#-*- encoding:utf-8 -*-

 

__author__ = 'shouke'

 

import socket

import time

 

if __name__ == '__main__':

   if_sock_connected = False

   try:

     

       # Create a socket (SOCK_STREAM means a TCP socket)

       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

       # Connect to server and send data

       sock.connect(('10.118.52.26', 8000))

 

       if_sock_connected = True # 标记socket是否已连接

       i = 0

 

       while i < 100:

           if i == 6:

               sock.sendall(bytes('bye\n', "utf-8"))

           else:

               sock.sendall(bytes('hello world with tcp\n', "utf-8"))

 

           # Receive data from the server

           received = str(sock.recv(1024), "utf-8")

           logger.info('receive data from server%s' % received)

           if received == 'bye':

               break

 

           time.sleep(5)

 

           i += 1

   except Exception as e:

       logger.error('程序运行出错:%s' % e)

   finally:

       if if_sock_connected:

           sock.close()

 

运行结果

 

 

 

函数说明:

BaseServer.serve_forever(poll_interval=0.5)

处理shudown请求除外的请求。

 

有关socket说明

socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

使用给定的地址家族,socket 类型,协议号创建一个新的socket。

family:默认为AF_INET,其它可选值有AF_INET6, AF_UNIX, AF_CAN or AF_RDS

type:默认为SOCK_STREAM,其它可选值有 SOCK_DGRAM, SOCK_RAW ,或者其它SOCK_XXX常量

protocol:通常为0或者忽略,当family为AF_CAN时,为CAN_RAW、CAN_BCM

 

 

Socket 对象

socket.close()

标记socket为closed

 

close()释放与连接关联的资源,但不一定立即关闭连接。如果要及时关闭连接,请在调用close()之前调用shutdown()。

 

socket.connect(address)

连接给定地址的远程socket

 

 

socket.recv(bufsize[, flags])

从socket接收数据。返回值即为接收的数据。

buffsize:每次接收的最大数据量。.

flags默认为0

 

注意:为了同硬件和网络设备最佳匹配,buffsize应该为一个相对小的2次幂,比如4096

 

socket.sendall(bytes[, flags])

发送字节数据到socket。不同于send方法,该方法会持续发送bytes参数给定的数据,直到所有数据被发送、错误发生。如果发送成功,则返回None,否则抛出异常。没有方法判断到底成功发送了多少数据

 

socket.send(bytes[, flags])

发送字节数据到socket。返回发送字节数,如果只传输了部分数据,程序会尝试发送剩余数据。

 

更多资料参考官方文档,socket模块

 

 

服务端(多线程服务器)

#!/usr/bin/env python 3.4.0

#-*- encoding:utf-8 -*-

 

__author__ = 'shouke'

 

import socket

import threading

import socketserver

 

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

 

   def handle(self):

       while True:

           # self.request即为与客户端连接的TCP socker

           self.data = self.request.recv(1024).decode('utf-8').strip()

           cur_thread = threading.current_thread()

           print('%s receive data from client[host%s port%s]%s' % (cur_thread.name, self.client_address[0], self.client_address[1], self.data))

 

           if self.data == 'bye':

               self.request.sendall(bytes('bye', encoding='utf-8'))

               self.request.close()

               break

           else:

               self.request.sendall((cur_thread.name + ' ' + self.data.upper()).encode('utf-8'))

 

 

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):

   pass

 

def client(ip, port, message):

   with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:

       sock.connect((ip, port))

       sock.sendall(bytes(message, 'ascii'))

       response = str(sock.recv(1024), 'ascii')

       print("Received: {}".format(response))

 

if __name__ == "__main__":

   # 如果设置端口为0,则表示任意未被占用端口

   HOST, PORT = "localhost", 9000

 

   server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)

   ip, port = server.server_address

 

   # 开启该server的一个线程,该线程会为每个请求开启更多的线程

   server_thread = threading.Thread(target=server.serve_forever)

   # server退出时,终止线程

   #server_thread.setDaemon(True)

 

   server_thread.start()

   print("Server loop running in thread:", server_thread.name)

 

   # server.shutdown()

   # server.server_close()

 

 

客户端

#!/usr/bin/env python 3.4.0

#-*- encoding:utf-8 -*-

 

__author__ = 'shouke'

 

import socket

import time

 

if __name__ == '__main__':

   if_sock_connected = False

   try:

       # 创建一个socket (SOCK_STREAM 表示为TCP socket)

       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

       # 连接到服务器

       sock.connect(('localhost', 9000))

 

       # 发送数据

       if_sock_connected = True

       i = 0

       while i < 100:

           if i == 6:

               sock.sendall(bytes('bye\n', "utf-8"))

           else:

               sock.sendall(bytes('hello world with tcp\n', "utf-8"))

               print("sent data to server{}".format(bytes('hello world with tcp\n', "utf-8")))

           # 从服务器接收数据

           received = str(sock.recv(1024), "utf-8")

           print('receive data from server%s' % received)

           if received == 'bye':

               break

           time.sleep(1)

           i += 1

   except Exception as e:

       print('程序运行出错:%s' % e)

   finally:

       if if_sock_connected:

           sock.close()

 

 

 

运行结果

 

 

 

 

 

更多资料,烦参考官方文档,socketserver模块。

目录
相关文章
|
1月前
|
网络协议 Python
|
1月前
|
测试技术 网络安全 数据安全/隐私保护
Paramiko是一个用于处理SSHv2协议的Python库
Paramiko是一个用于处理SSHv2协议的Python库
30 3
|
2月前
|
数据采集 JSON API
🎓Python网络请求新手指南:requests库带你轻松玩转HTTP协议
本文介绍Python网络编程中不可或缺的HTTP协议基础,并以requests库为例,详细讲解如何执行GET与POST请求、处理响应及自定义请求头等操作。通过简洁易懂的代码示例,帮助初学者快速掌握网络爬虫与API开发所需的关键技能。无论是安装配置还是会话管理,requests库均提供了强大而直观的接口,助力读者轻松应对各类网络编程任务。
116 3
|
2月前
|
机器学习/深度学习 JSON API
HTTP协议实战演练场:Python requests库助你成为网络数据抓取大师
在数据驱动的时代,网络数据抓取对于数据分析、机器学习等至关重要。HTTP协议作为互联网通信的基石,其重要性不言而喻。Python的`requests`库凭借简洁的API和强大的功能,成为网络数据抓取的利器。本文将通过实战演练展示如何使用`requests`库进行数据抓取,包括发送GET/POST请求、处理JSON响应及添加自定义请求头等。首先,请确保已安装`requests`库,可通过`pip install requests`进行安装。接下来,我们将逐一介绍如何利用`requests`库探索网络世界,助你成为数据抓取大师。在实践过程中,务必遵守相关法律法规和网站使用条款,做到技术与道德并重。
52 2
|
2月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
67 3
|
2月前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
79 8
|
1月前
|
缓存 网络协议 Linux
Python渗透测试之ARP毒化和协议应用
Python渗透测试之ARP毒化和协议应用
|
3月前
|
网络协议 Unix Linux
python socket和socketserver
python socket和socketserver
|
2月前
|
Python
HTTP协议不再是迷!Python网络请求实战,带你走进网络世界的奥秘
本文介绍了HTTP协议,它是互联网信息传递的核心。作为客户端与服务器通信的基础,HTTP请求包括请求行、头和体三部分。通过Python的`requests`库,我们可以轻松实现HTTP请求。本文将指导你安装`requests`库,并通过实战示例演示如何发送GET和POST请求。无论你是想获取网页内容还是提交表单数据,都能通过简单的代码实现。希望本文能帮助你在Python网络请求的道路上迈出坚实的一步。
63 0
|
3月前
|
SQL 关系型数据库 API
Python 开发环境的准备以及一些常用类库模块的安装
在学习和开发Python的时候,第一步的工作就是先准备好开发环境,包括相关常用的插件,以及一些辅助工具,这样我们在后续的开发工作中,才能做到事半功倍。下面介绍一些Python 开发环境的准备以及一些常用类库模块的安装和使用的经验总结,供大家参考了解。