之前曾有php版的websocket封装包。见Websocket——php实战,近期使用python做一些功能,须要用到对websocket的操作,因此,參照之前的实现,实现了这个python版本号。

源代码见https://github.com/OshynSong/wspy

总体实现起来,须要在建立socket监听port。这须要用到socket标准库模块。之后。须要对对网络字节流进行操作,这个方面python有struct标准库模块。这个很好用;另外涉及到加密解密操作,还有hashlib模块和sha模块等使用。特别在此总结一下。目的主要是

1 备忘

2. 总结与思考

1 socket 操作

1 本地Socket建立

建立TCPserver的一般流程:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((addr,port))
sock.listen(10)

建立好本地socket,并绑定地址与port进行监听。

2 并发连接策略

之后,须要使用不同的策略处理多个client连接的问题,最普通的处理方式就是直接使用accept堵塞,这样server端每次仅仅能处理一个client连接。然后python标准库提供了select模块,里面有select、poll和epoll这些不同的并发连接的处理策略。当中poll和epoll仅仅能在linux下使用,并且epoll在linux 2.6之后的版本号才干使用。当然并发处理效果来看。epoll比poll性能更好。poll比select性能更优。

可是select确能够在多种平台下使用,为了兼容Windows系统。本次实现中使用的是select策略,详细例如以下:

... #接上述socket建立代码
while True:
rs, ws, es = select.select([sock], [], [])
for r in rs:
if r is sock: #r 是server端socket
cliSock,addr = r.accept()
r.connect(cliSock) #建立于client连接
else:
try:
data = r.recv(bufferLen)
... #处理client连接发送的数据
...

poll方法也是select模块内的方法。使用起来比select更简单。首先使用poll建立一个poll对象,然后使用它的register方法注冊一个文件描写叙述符,unregister方法能够移除注冊对象。之后能够调用poll方法得到(fd,event)格式的列表,fd是文件描写叙述符。event代表发生的事件。

event是一个位掩码。能够使用select模块的常量进行按位操作。

select模块中polling事件常量:

事件名 描写叙述
POLLIN 读取来自文件描写叙述符的数据
POLLPRI 读取来自文件描写叙述符的紧急数据
POLLOUT 文件描写叙述符的数据已准备好。可无堵塞写入
POLLERR 与文件描写叙述符有关的错误情况
POLLHUP 挂起,连接丢失
POLLNVAL 无效请求,连接没有打开

以下是使用poll策略的演示样例代码:

... #接上述socket建立代码
fdmap = {sock.fileno() : s}
p = select.poll()
p.register(sock)
while True:
events = p.poll()
for fd,event in events:
if fd in fdmap: #本地socket
c,addr = sock.accept()
print 'Connected from ', addr
p.register(c)
fdmap[c.fileno()] = c
elif event & select.POLLIN:
data = fdmap[fd].recv(buffer)
...#数据操作
elif event & select.POLLERR: #断开连接
p.unregister(fd)
del fdmap[fd]
......

2 Struct处理字节数据

这个标准库模块就是用来转换python的数据值与C风格的数据类型的交互,特别是二进制文件和网络的字节数据。基本的方法:

struct.pack(fmt, v1, v2…)

struct.pack_into(fmt, buffer, offset, v1, v2…) (将v1,v2等值依照fmt格式pack到buffer字符串以offset開始的之后的位置)

struct.unpack(fmt, string)

struct.unpack_from(fmt, buffer [, offset=0])

struct.calcsize(fmt) (计算fmt的长度)

上面主要是直接使用struct模块的方法,每一个fmt都须要单独进行。假设须要重用。能够使用struct提供的Struct类。使用fmt实例化Struct对象之后,调用相似方法就能够进行重用。并且这样使用对象调用的性能更好,比直接使用上述方法调用效率更高。

pack(v1,v2…)

pack_into(buffer, offset, v1, v2 …)

unpack(string)

unpack_from(buffer, offset=0)

format : 返回实例化Struct对象使用的fmt字符串

size:返回fmt字符串的长度

当中最关键的format字符串的使用。

首先是字节顺序:

Character Byte order Size Alignment
@ native native native
= native standard none
< little-endian standard none
> big-endian standard none
! network (= big-endian) standard none

然后就是format使用特殊字符,见下表:

Format C Type Python type Standard size
x pad byte no value
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer 4
l long integer 4
L unsigned long integer 4
q long long integer 8
Q unsigned long long integer 8
f float float 4
d double float 8
s char[] string
p char[] string
P void * integer

3 加密解密处理

hashlib标准库模块提供了经常使用的全部加密解密hash方法。使用到的有:

hashlib.update(arg):将hash对象使用arg字符串更新。多次调用相当于将全部arg字符串连接到一起

hashlib.digest() : 返回传如到update方法的字符串的hash值

hashlib.hexdigest():返回hash值的十六进制字符串表示

hashlib.copy():返回一个hash值的副本

websocket中在握手阶段须要获取到client的key,然后使用sha1和base64进行加密处理后发送到client进行握手。

    sha1Encrypt = sha1(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest()
acceptKey = base64.b64encode(sha1Encrypt)

总体来说,使用python实现这些操作很方便。与php相比更加简洁。彰显了python语言简洁的本质!

python实现的websocket总结 —— wspy的更多相关文章

  1. Python中的WebSocket

    一.Websockets介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信 ...

  2. python测试基于websocket协议的即时通讯接口

    随着html5的广泛应用,基于websocket协议的即时通讯有了越来越多的使用场景,本文使用python中的websocket-client模块来做相关的接口测试 import webclient ...

  3. Python开发 之 Websocket 的使用示例

    1.唠唠叨叨 最近又回顾了下Websocket,发现已经忘的七七八八了.于是用js写了客户端,用python写了服务端,来复习一下这方面的知识. 2.先看一下效果吧 2.1.效果1(一个客户端连上服务 ...

  4. python简单实现websocket

    协议选择的是新的Hybi-10,参考文章如下: http://www.cnblogs.com/zhuweisky/p/3930780.html http://blog.mycolorway.com/2 ...

  5. python与html5 websocket开发聊天对话窗

    1.下载必须的包 https://github.com/Pithikos/python-websocket-server,解压缩并把文件夹名‘python-websocket-server-maste ...

  6. python实现的WebSocket客户端

    code #coding=utf- import json import time from websocket import create_connection ws = create_connec ...

  7. python脚本测试websocket接口协议

    import websocket url = 'wss://host:port/rt/tr' #websocket连接地址 ws = websocket.create_connection(url) ...

  8. python实现建立websocket通信

    实现代码如下: #websocket协议通信 import threading import time import websocket def when_message(ws, message): ...

  9. python websocket学习使用

    前言 今天看了一些资料,记录一下心得. websocket是html5引入的一个新特性,传统的web应用是通过http协议来提供支持,如果要实时同步传输数据,需要轮询,效率低下 websocket是类 ...

随机推荐

  1. BZOJ 4809: 皇后

    题目大意: n皇后问题,有些格子不能放. 题解: 直接暴力,并不用加优化就能过. 代码: #include<cstdio> using namespace std; int cc,n,an ...

  2. java 邮箱验证

    1.需要加入发送邮件的mail.jar: http://www.oracle.com/technetwork/java/javamail/index-138643.html 2.将字符串通过MD5进行 ...

  3. 【Luogu】P1681最大正方形2(异或运算,DP)

    题目链接 不得不说attack是个天才.读入使用异或运算,令que[i][j]^=(i^j)&1,于是原题目变成了求que数组的最大相同值. 然而我还是不理解为啥,而且就算简化成这样我也不会做 ...

  4. cf493E Vasya and Polynomial

    Vasya is studying in the last class of school and soon he will take exams. He decided to study polyn ...

  5. LA 4973异面线段

    题目大意:给两条线段求他们间的最小距离的平方(以分数形式输出). 贴个模版吧!太抽象了. #include<cstdio> #include<cmath> #include&l ...

  6. uva 1426 离散平方根

    1426 - Discrete Square Roots Time limit: 3.000 seconds A square root of a number x <tex2html_verb ...

  7. STL学习笔记(四) 迭代器

    条款26:iterator 优先于 const_iterator, reverse_iterator, const_reverse_iterator iterator, reverse_iterato ...

  8. 【Git】Git 本地的撤销修改和删除操作

    一:撤销操作 比如我现在在readme.txt文件里面增加一行 内容为555555555555,我们先通过命令查看如下: 在我未提交之前,我发现添加5555555555555内容有误,所以我得马上恢复 ...

  9. hdu 4430 Yukari's Birthday 枚举+二分

    注意会超long long 开i次根号方法,te=(ll)pow(n,1.0/i); Yukari's Birthday Time Limit: 12000/6000 MS (Java/Others) ...

  10. Linux下重启就需要重新激活eth0的解决办法(ifup eth0)

    新安装linux系统,网卡不能自动激活去获取ip,每次都需要手工执行以下命令 ifup eth0 后续通过将ONBOOT=yes这句就能开机启动自动激活,就可以解决问题 vim /etc/syscon ...