python实现websocket服务端

ws.py是服务端,文件内容如下

#!/usr/bin/env python
import socket
import base64
import hashlib
import struct
from select import select
class dryWebSocket():
    #####
    @staticmethod
    def handShake(serverHandle):
        key = ''
        data = serverHandle.recv(8192)
        for line in data.split('\r\n\r\n')[0].split('\r\n')[1:]:
            k, v = line.split(': ')
            if k == 'Sec-WebSocket-Key':
                key = base64.b64encode(hashlib.sha1(v + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())
        response = 'HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept:%s\r\n\r\n' % key
        serverHandle.send(response)
        return True
    #####
    @staticmethod
    def recv(serverHandle, size=8192):
        data = serverHandle.recv(size)
        if not len(data):
            return False
        length = ord(data[1]) & 127
        if length == 126:
            mask = data[4:8]
            raw = data[8:]
        elif length == 127:
            mask = data[10:14]
            raw = data[14:]
        else:
            mask = data[2:6]
            raw = data[6:]
        ret = ''
        for cnt, d in enumerate(raw):
            ret += chr(ord(d) ^ ord(mask[cnt%4]))
        return ret
    #####
    @staticmethod
    def send(serverHandle, data):
        head = '\x81'
        if len(data) < 126:
            head += struct.pack('B', len(data))
        elif len(data) <= 0xFFFF:
            head += struct.pack('!BH', 126, len(data))
        else:
            head += struct.pack('!BQ', 127, len(data))
        serverHandle.send(head + data)
##########################################################################################
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
socketList = set()
##########
def run(ip, port, count, function, debug):
    server.bind((ip, port))
    server.listen(count)
    socketList.add(server)
    print 'websocket server start on port %d' % port
    while True:
        r, w, e = select(socketList, [], [])
        for sock in r:
            if sock == server:
                serverHandle, addr = sock.accept()
                if dryWebSocket.handShake(serverHandle):
                    socketList.add(serverHandle)
            else:
                data = dryWebSocket.recv(sock)
                if not data:
                    socketList.remove(sock)
                else:
                    function(sock, data, debug)
##########
def dataDo(serverHandle, data, debug):
    if debug:
        print data
    dryWebSocket.send(serverHandle, data)
##########
if __name__ == '__main__':
    run('0.0.0.0', 7000, 100, dataDo, True)

ws.html是客户端,文件内容如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>webSocketClient</title>
</head>
<body>
<table>
    <tr>
        <td>
            <p><input type="text" id="ip" value="127.0.0.1"/></p>
            <p><input type="text" id="port" value="7000"/></p>
            <p><input type="text" id="data" value="test"/></p>
            <p><input type="button" value="打开连接" onclick="theOpen()"/></p>
            <p><input type="button" value="发送输入数据" onclick="theInputData()"/></p>
            <p><input type="button" value="发送随机数据" onclick="theRandData()"/></p>
            <p><input type="button" value="清空日志" onclick="theClear()"/></p>
        </td>
    </tr>
</table>
<p id="show"></p>
<script type="text/javascript">
var $$=function(id){return document.getElementById(id);}
var client='';
var ipElement=$$('ip');
var portElement=$$('port');
var dataElement=$$('data');
var showElement=$$('show');
/**/
function theOpen(){
    if(client==''){
        client=new WebSocket('ws://'+ipElement.value+':'+portElement.value);
        client.onopen=function(){
            onOpenHandle();
        };
        client.onmessage=function(event){
            onMessageHandle(event);
        };
        client.onclose=function(event){
            onCloseHandle();
        };
    }
    else{
        showMessage('has opened');
    }
}
function theInputData(){
    client.send(dataElement.value);
}
function theRandData(){
    client.send(Math.random());
}
function theClear(){
    showElement.innerHTML='';
}
/**/
function onOpenHandle(){
    showMessage('open');
}
function onMessageHandle(event){
    showMessage('receive:'+event.data);
}
function onCloseHandle(){
    showMessage('close');
    client='';
}
/**/
function showMessage(msg){
    var html=showElement.innerHTML;
    showElement.innerHTML=html+"<br>"+msg;
}
</script>
</body>
</html>

 

转载于:https://my.oschina.net/mickelfeng/blog/903837

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值