我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python 学习笔记 - socket

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python 学习笔记 - socket

前面学习的例子都是单线程的socket收发;如果有多个用户同时接入,那么除了第一个连入的,后面的都会处于挂起等待的状态,直到当前连接的客户端断开为止。

通过使用socketserver,我们可以实现并发的连接。

socketserver的使用很简单:


首先看个简单的例子


服务端:

自己定义一个类,继承socketserver.baserequesthandler;

然后定义一个方法 handle()

然后通过socketserver.threadingTCPServer指定套接字和自己定义的类,每次当客户端连入的时候,会自动实例化一个对象,然后通过server_forever()不断循环读写数据。


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author Yuan Li
import socketserver
class mysocketserver(socketserver.BaseRequestHandler):
    def handle(self):
        conn = self.request
        conn.sendall(bytes("Welcome to the Test system.", encoding='utf-8'))
        while True:
            try:
                data = conn.recv(1024)
                if len(data) == 0: break
                print("[%s] sends %s" % (self.client_address, data.decode()))
                conn.sendall(data.upper())
            except Exception:
                break
if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1', 8009), mysocketserver)
    server.serve_forever()


客户端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author Yuan Li
import socket
ip_port = ('127.0.0.1', 8009)
s = socket.socket()
s.connect(ip_port)
data = s.recv(1024)
print(data.decode())
while True:
    send_data = input("Data>>>")
    s.send(bytes(send_data, encoding='utf-8'))
    recv_data = s.recv(1024)
    print(recv_data.decode())


上面的效果是多个客户端可以同时连入服务器,输入字母,返回大写字母。


客户端没啥好说的,这个和单线程的操作一样;但是服务器咋一看很混乱。我们可以通过剖析源码来弄清他的执行过程。


这个类的基本结构是如下所示的,我们按照顺序来跑一次看看他怎么调用的


wKiom1gNmjTj7TH2AAK6-Px_JOg280.png


1. 首先执行的这句话,很明显ThredingTCPServer是一个类,点进去看看他的实例化过程

server = socketserver.ThreadingTCPServer(('127.0.0.1', 8009), mysocketserver)

2. 点着Ctrl键,点击这个类,PyCharm会自动打开对应的源码,可以看见这个类又继承了两个父类ThredingMixIn和TCPServer

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

因为他的内容是pass,啥也没做,根据继承的顺序,我们继续往上(从左到右)找init构造函数; 


3. ThreadingMixIn里面没有构造函数,那就继续往右找,TCPServer里面倒是有构造函数,但是他又调用了他父类BaseServer的构造函数,顺着看上去,发现他就是封装了几个值在里面,注意   self.RequestHandlerClass = RequestHandlerClass把我们自己定义的类传进去了

    def __init__(self, server_address, RequestHandlerClass):
        """Constructor.  May be extended, do not override."""
        self.server_address = server_address
        self.RequestHandlerClass = RequestHandlerClass
        self.__is_shut_down = threading.Event()
        self.__shutdown_request = False


4.接下来,在TCPServer的构造函数里面,他执行了bind,listen的操作,这个和单线程的操作是一样的。到此为止,一个初始化的过程基本就完成了。


5.接下来,执行了server.serve_forever()的操作,我们看看内部是怎么调用的。在这个函数里面,使用了selector的IO多路复用的技术,循环的读取一个文件的操作。接着调用了_handle_request_noblock()函数

  try:
            # XXX: Consider using another file descriptor or connecting to the
            # socket to wake this up instead of polling. Polling reduces our
            # responsiveness to a shutdown request and wastes cpu at all other
            # times.
            with _ServerSelector() as selector:
                selector.register(self, selectors.EVENT_READ)
                while not self.__shutdown_request:
                    ready = selector.select(poll_interval)
                    if ready:
                        self._handle_request_noblock()
                    self.service_actions()


6.每次调用函数的时候都记住查找的顺序,从下往上,从左往右,最后在最上面的BaseServer再次找到这个函数,这个函数里面又调用了 process_request函数

        """
        try:
            request, client_address = self.get_request()
        except OSError:
            return
        if self.verify_request(request, client_address):
            try:
                self.process_request(request, client_address)

一定要记住继承的顺序!!顺序!!顺序!!


因为baseserver自己有process_request的方法,ThreadingTCPServer也有同名的方法,当他调用的时候,按照顺序,是执行的ThreadingTCPServer里面的方法!!


wKioL1gNoxaThqRFAAB5Z_o7GWs657.png


wKiom1gNouDj48lSAABEODjRuN0521.png


 可以看见他开了一个多线程

  def process_request(self, request, client_address):
        """Start a new thread to process the request."""
        t = threading.Thread(target = self.process_request_thread,
                             args = (request, client_address))
        t.daemon = self.daemon_threads
        t.start()

在他调用的process_request_thread里面,他又调用了finsih_request

    def process_request_thread(self, request, client_address):
        """Same as in BaseServer but as a thread.
        In addition, exception handling is done here.
        """
        try:
            self.finish_request(request, client_address)
            self.shutdown_request(request)
        except:
            self.handle_error(request, client_address)
            self.shutdown_request(request)


finish_request里面有对我们自定义的类做了一个实例化的操作

    def finish_request(self, request, client_address):
        """Finish one request by instantiating RequestHandlerClass."""
        self.RequestHandlerClass(request, client_address, self)


因为我们自定义的类没有构造函数,他会去父类寻找,父类里面会尝试执行handle()方法,这就是为什么我们需要在自定义的类里面定义一个同名的方法,然后把所有需要执行的内容都放在这里。


 def __init__(self, request, client_address, server):
        self.request = request
        self.client_address = client_address
        self.server = server
        self.setup()
        try:
            self.handle()


到此,socketserver一个完整的过程就结束了

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python 学习笔记 - socket

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python 学习笔记 - socket

前面学习的例子都是单线程的socket收发;如果有多个用户同时接入,那么除了第一个连入的,后面的都会处于挂起等待的状态,直到当前连接的客户端断开为止。通过使用socketserver,我们可以实现并发的连接。socketserver的使用很
2023-01-31

Python学习笔记

Python介绍Python是一种解释型、面向对象的语言。官网:www.python.orgPython环境解释器:www.python.org/downloads运行方式:交互模式。在IDLE中运行。脚本模式。文件的后缀名为.py。
2023-01-30

Python 学习笔记

rs=Person.objects.all()all返回的是QuerySet对象,程序并没有真的在数据库中执行SQL语句查询数据,但支持迭代,使用for循环可以获取数据。print rs.query 会打印出原生sql语句rs=Person
2023-01-31

python学习笔记--趣学Python

由反弹球和球拍构成的游戏。球会在屏幕上飞过来,玩家要用球拍把它弹回去画布和画弹球引入模块#Tkinter -- Python的标准GUI库,Tk 接口,是python 内置的安装包from tkinter import *import ra
2023-01-31

Python学习笔记(1)

1 def sum_args(*args):2 return sum(args))3 4 def run_with_positional_args(func, *args):5 return func(*args)6
2023-01-31

Python 学习笔记 - SQLAlc

继续上一篇SQLAlchemy的学习之旅。多对多表的创建表Host和表HostUser通过表HostToHostUser关联在一起from sqlalchemy import create_enginefrom sqlalchemy.ext
2023-01-31

python scapy学习笔记

1. ubuntu下安装gnuplot 转自:http://blog.163.com/gz_ricky/blog/static/182049118201362501316961/2.安装PyX sudo pip install pyx==0
2023-01-31

python scrapy学习笔记

scrapy是python最有名的爬虫框架之一,可以很方便的进行web抓取,并且提供了很强的定制型。一、安装scrapy# pip install scrapy二、基本使用1、初始化scrapy项目# scrapy startproject
2023-01-31

python egg学习笔记

原文链接:http://www.worldhello.net/2010/12/08/2178.html经常接触Python的同学可能会注意到,当需要安装第三方python包时,可能会用到easy_install命令。easy_install
2023-01-31

Python 学习笔记 - Memcac

Memcached是一个分布式内存对象缓存系统,他把数据缓存在内存里面来减少对数据库的访问,从而提高动态网页的访问速度。他的基本结构是key/value(键值对)。下面看看在Python里面如何使用。首先来安装一下服务器端,豆子直接在一个C
2023-01-31

Python学习笔记(matplotli

Python学习笔记--在Python中如何调整颜色和样式  参靠视频:《Python数据可视化分析 matplotlib教程》链接:https://www.bilibili.com/video/av6989413/?p=6所用的库及环境:
2023-01-30

python-memcached学习笔记

介绍:  memcached是免费、开源、高性能、分布式内存对象的缓存系统(键/值字典),旨在通过减轻数据库负载加快动态web应用程序的使用。  数据类型:只用一种字符串类型1:安装sudo apt-get install memcache
2023-01-31

Python学习笔记四(Python

Python os模块提供了一个统一的操作系统接口函数,通过python os模块可以实现对系统本身的命令,文件,目录进行操作,官方参考文档( http://docs.python.org/library/os)。1)os.sep 可以取代
2023-01-31

Python学习笔记-SQLSERVER

环境 : python3.6 / win10 / vs2017 / sqlserver2017一、需要安装的包pymssqlpip install pymssql二、pymssql模块的介绍pymssql 包 有modules:pymssq
2023-01-30

Python Paste 学习笔记

一、写在前面这篇文章主要介绍了Python的Paste库的使用,学习过程中主要参考官网文档以及自己的理解,整理成笔记以便后续自己查阅。 如果转载,请保留作者信息。 邮箱地址:jpzhang.ht@gmail.com Python Pa
2023-01-31

python学习笔记 --- prin

print 输出直接到文件里主要是python版本问题,语法不一样,这里记录一下。python 3.x#!/usr/bin/env python3 #coding:utf-8K = 10f = open("./output/recard"
2023-01-31

Python学习笔记 --- pprin

使用 pprint 模块pprint 模块( pretty printer )用于打印 Python 数据结构. 当你在命令行下打印特定数据结构时你会发现它很有用(输出格式比较整齐, 便于阅读).import pprintdata = (
2023-01-31

python——Matplotlib学习笔记

  Matplotlib是pyhon中一个强大的绘图图,可以理解为 MatLab 开源替代,鉴于MatLab的内存之大及安装之复杂,决定先学学Matplotlib这个库。  1Matplotlib的安装  window:  打开cmd,: 
2023-06-02

python学习笔记(3)

在大概了解了程序之后,我也买了本python书学习一下,因为现在新版的python3.4.0已经不再兼容2.x.x的内容,书虽然很新,但是有些例子还是用的过去的。1.比如在3.0中print 42不能再产生输出了,要改成print(42)>
2023-01-31

Python学习笔记(1)

Python开发框架:      a.Python基础;      b.网络编程;      c.WEB框架;      d.设计模式+算法;      e.项目阶段;开发:  开发语言:      高级语言:Python,Java,  
2023-01-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录