Python 异步收发数据socket实战

Python 写了一个收发数据用的socket,自己测并发可以达到10K+,用了20分钟撸了一个,不多讲直接晒代码

#!/usr/bin/python
#coding:utf-8
# author:51reboot.com
import socket,select
import os,sys,copy

HOST = ‘0.0.0.0‘
PORT = 8089
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)     # 释放端口
s.setblocking(0)                                            # 设置为非阻塞
s.bind((HOST,PORT))
s.listen(10)                                                # 等待对列

# listen: accept -> read -> process -> write -> closing
# accpet: read -> process -> wriet -> closing

# 状态机 模板
STATE_M = {
    -1:{                            # sock 
        ‘s‘:‘read‘,              # sock 状态
        ‘r‘:{                       # read 的信息
            ‘have‘:0,               # 已读的字节数
            ‘need‘:10,              # 要读的字节数
        },
        ‘w‘:{                       # write 的数据
            ‘have‘:0,               # 已经write 的数据
            ‘need‘:0,               # 需要write 的数据
        },
        ‘d‘:‘‘,         # 用于存放数据
    },
}

STATE= {}

def state_machine(sock):
    if sock == s:
        # 监听socket
        conn,addr = s.accept()
        s.setblocking(0)                    # 设置为非阻塞
        STATE[conn] = copy.deepcopy(STATE_M[-1])             # 给这个连接赋初值
        R_LIST.append(conn)                 # 将sock加入到 需要R_LIST信息的列表
    else:
        # 已经accept的socket
        stat = STATE[sock][‘s‘]             # 保存 sock 的状态信息
        if stat == ‘read‘:     
            #如果状态为read,则需要进行读操作
            if STATE[sock][‘r‘][‘need‘] == 0:
                #  如果 client 发过来的数据全部读取完了
                R_LIST.remove(sock)                                     # 将sock 需要读取的列表中remove
                STATE[sock][‘s‘] = ‘process‘                            # 修改sock的状态
                state_machine(sock)                                     # 进行一次回调
            else:
                one_read = sock.recv(STATE[sock][‘r‘][‘need‘])              # 读取指定字节数
                STATE[sock][‘d‘] += one_read                                # 更新读取的字节数
                # 需要重新整理已读取的数据与还需要读取的数据
                STATE[sock][‘r‘][‘have‘] += len(one_read)
                STATE[sock][‘r‘][‘need‘] -= len(one_read)
                if STATE[sock][‘r‘][‘have‘] == 10:
                    # 读完头信息开始读取主体内容
                    STATE[sock][‘r‘][‘need‘] += int(STATE[sock][‘d‘])       # 修改接下来需要读取的字节数
                    STATE[sock][‘d‘] = ‘‘                                   # 清空已接收到的数据
        elif stat == ‘process‘:
            # 读完了client发送的数据后,开始给client返回数据
            response = STATE[sock][‘d‘][::-1]                               # 反转字符
            STATE[sock][‘d‘] = "%010d%s" % (len(response),response)         # 更新接收到的数据
            STATE[sock][‘w‘][‘need‘] = len(STATE[sock][‘d‘])                # 更新需要发出的字节数
            STATE[sock][‘s‘] = ‘write‘                                      # 修改sock的状态为写
            W_LIST.append(sock)                                             # 将sock 加入到 W_LIST
        elif stat == ‘write‘:
            print "wirite", STATE
            # 如果状态为 write,同向client发送数据
            last_have_send = STATE[sock][‘w‘][‘have‘]                       # 保存已发送的字节数
            have_send = sock.send(STATE[sock][‘d‘][last_have_send:])        # 向client发送数据,返回返回了多少个字节
            STATE[sock][‘w‘][‘have‘] += have_send                           # 修改已发出的字节
            STATE[sock][‘w‘][‘need‘] -= have_send                           # 修改需要发出的字节
            if STATE[sock][‘w‘][‘need‘] == 0 and STATE[sock][‘w‘][‘have‘] != 0:
                # 如果数据已发完,则关闭sock
                STATE[sock][‘s‘] = ‘closing‘
        elif stat == ‘closing‘:
            print "closing", STATE
            
            # 关闭连接
            STATE.pop(sock)                                                 # 将sock从状态里删除
            try:
                W_LIST.remove(sock)                                             # 将sock从w_list里删除
            except ValueError:
                pass
            sock.close()                                                    # 关闭连接

R_LIST = [s]            # 可读的sock列队
W_LIST = []             # 可写的sock队列
non_stop = True
while True:
    try:
        r_socks,w_socks,err_socks = select.select(R_LIST,W_LIST,[])
    except socket.error,e:
        print e
    for sock in r_socks:
        state_machine(sock)
    for sock in w_socks:
        state_machine(sock)

有多交流请加QQ群365534424 Reboot运维开发实战

时间: 2024-08-28 06:08:59

Python 异步收发数据socket实战的相关文章

python异步socket编程之二

三.异步client与异步server的通信 1. 服务端代码 pythone socket的server段,开放三个端口:10000,10001,10002. 例子中是每个server绑定一个端口,测试的时候需要分别开3个shell,分别运行. 这太麻烦了,就分别用三个Thread来运行这些services #!/usr/bin/env python # # -*- coding:utf-8 -*- # File: multithrd_socket_server.py # import opt

数据科学实战手册(R+Python)书中引用资料网址

本文会持续将<数据科学实战手册(R+Python)>一书中的附带参考资料网址手打出来, 方便访问. 由于书中的参考资料网址太多, 这个文档将可能花费一段时间才能完成. 第一章 P7  Rstdio (http://www.rstdio.com/) 参考Gettinng Started with R文章: http://support.rstdio.com/hc/en-us/articles/201141096-Getting-Started-With-R 访问RStdio的主页: http:/

Python异步Socket编程

异步网络据说能极大的提高网络server的连接速度,所以打算写一个专题,来学习和了解异步网络.因为Python有个非常出名的异步Lib:Twisted,所以就用Python来完成. OK,首先写一个pythone socket的server段,对开放三个端口:10000,10001,10002.krondo的例子中是每个server绑定一个端口,测试的时候需要分别开3个shell,分别运行.这太麻烦了,就分别用三个Thread来运行这些services. Java代码   import optp

分享《数据科学实战手册(R+Python)》中文PDF+英文PDF+源代码

下载:https://pan.baidu.com/s/1Iw0pHxKqp2mKC9ksR5wfPQ 更多分享资料:https://www.cnblogs.com/javapythonstudy/ <数据科学实战手册(R+Python)>中文PDF+英文PDF+源代码中文PDF,带书签目录,354页:英文PDF,带书签目录,396页:两版对比学习.配套源代码. 中文版如图: 原文地址:https://www.cnblogs.com/javapythonstudy/p/9924670.html

Spark2.x+Python大数据机器学习实战视频教程

提取码:6o68 课程学习:https://pan.baidu.com/s/13kOswCBRsnXBJWsPGBZDqQ 机器学习是近二十来年兴起的多领域学科,机器学习算法可从数据中建立模型,并利用模型对未知数据进行预测.机器学习技术不断进步,应用相当广泛,例如推荐引擎.定向广告.需求预测.垃圾邮件过滤.医学诊断.自然语言处理.搜索引擎.诈骗侦测.证券分析.视觉辨识.语音识别.手写识别等. 为什么近年来机器学习变得如此热门,各大公司都争相投入?因为机器学习需要大量数据进行训练.大数据的兴起带来

转-python异步IO-asyncio

原文连接 http://blog.chinaunix.net/uid-190176-id-4223282.html 前言 异步操作在计算机软硬件体系中是一个普遍概念,根源在于参与协作的各实体处理速度上有明显差异.软件开发中遇到的多数情况是CPU与IO的速度不匹配,所以异步IO存在于各种编程框架中,客户端比如浏览器,服务端比如node.js.本文主要分析Python异步IO. Python 3.4标准库有一个新模块asyncio,用来支持异步IO,不过目前API状态是provisional,意味着

Python异步IO --- 轻松管理10k+并发连接

前言 异步操作在计算机软硬件体系中是一个普遍概念,根源在于参与协作的各实体处理速度上有明显差异.软件开发中遇到的多数情况是CPU与IO的速度不匹配,所以异步IO存在于各种编程框架中,客户端比如浏览器,服务端比如node.js.本文主要分析Python异步IO. Python 3.4标准库有一个新模块asyncio,用来支持异步IO,不过目前API状态是provisional,意味着不保证向后兼容性,甚至可能从标准库中移除(可能性极低).如果关注PEP和Python-Dev会发现该模块酝酿了很长时

Python(七)Socket编程、IO多路复用、SocketServer

本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 功能: sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) 参数一:地址簇 socket.AF_INET IPv4(默认)

转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理还是有必要的.下面记录下分别基于Select/Poll/Epoll的echo server实现.Python Select Server,可监控事件数量有限制: 1 2 3 4 5 6 7 8 9 10 11 12 13 14