zoukankan      html  css  js  c++  java
  • python 实现新版websocket协议 server

    python 实现新版websocket协议 server - 0x14 - ITeye技术网站

    websocket 和 正常 socket 使用方式有点不一样

    正常socket 客户端流程:

    连接 -> 连接成功 -> 接受数据 || 发送数据

    完事了

    正常socket 服务端流程:

    创建套接字 -> 绑定 -> 接受连接  -> 接受数据 || 发送数据

    完事了

    websocket 客户端流程:

    连接->  连接成功 -> 创建消息响应事件 -> 发送数据

    websocket 服务端流程

    创建套接字 -> 绑定 -> 接受连接 -> 接受websocket 发送过来的http头 -> 处理要回应的http头 ->

    回应客户端 -> 握手成功 -> 按照websocket数据格式接受发送数据

    确实稍微麻烦点

    现在开始用python来实现一个websocket server

    Python代码  收藏代码
    1. import socket,threading,struct  
    2.   
    3. #启动websocket server  
    4. def InitWebSocketServer():  
    5.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
    6.     try:  
    7.         sock.bind(("localhost",3398)) #绑定本地地址,端口3398  
    8.         sock.listen(100)  
    9.     except:  
    10.         print("Server is already running,quit")  
    11.         sys.exit()  
    12.     while True:  #创建一个死循环,接受客户端  
    13.         connection,address = sock.accept()  
    14.         if(handshake(connection) != False): #如果握手失败,不启动任务  
    15.             t = threading.Thread(target=DoRemoteCommand,args=(connection,))  
    16.             t.start()  
    17.   
    18.   
    19. #连接成功后回应给客户端进行握手  
    20. def handshake(client):  
    21.     headers = {}  
    22.     shake = client.recv(1024)  
    23.       
    24.     if not len(shake):  
    25.         return False  
    26.       
    27.     header, data = shake.split('\r\n\r\n'1)  
    28.     for line in header.split("\r\n")[1:]:  
    29.         key, value = line.split(": "1)  
    30.         headers[key] = value  
    31.       
    32.     if(headers.has_key("Sec-WebSocket-Key") == False):  
    33.         print("this socket is not websocket,close")  
    34.         client.close()  
    35.         return False  
    36.       
    37.     szOrigin = headers["Sec-WebSocket-Origin"]  
    38.     szKey = base64.b64encode(hashlib.sha1(headers["Sec-WebSocket-Key"] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())  
    39.     szHost = headers["Host"]  
    40.       
    41.     our_handshake = "HTTP/1.1 101 Switching Protocols\r\n" \  
    42.                     "Upgrade:websocket\r\n"\  
    43.                     "Connection: Upgrade\r\n"\  
    44.                     "Sec-WebSocket-Accept:"+ szKey + "\r\n" \  
    45.                     "WebSocket-Origin:" + szOrigin + "\r\n" \  
    46.                     "WebSocket-Location: ws://" + szHost + "/WebManagerSocket\r\n" \  
    47.                     "WebSocket-Protocol:WebManagerSocket\r\n\r\n"  
    48.                       
    49.     client.send(our_handshake)  
    50.     return True  
    51.   
    52. #接收客户端发送过来的消息,并且解包  
    53. def RecvData(nNum,client):  
    54.     try:  
    55.         pData = client.recv(nNum)  
    56.         if not len(pData):  
    57.             return False  
    58.     except:  
    59.         return False  
    60.     else:  
    61.         code_length = ord(pData[1]) & 127  
    62.         if code_length == 126:  
    63.             masks = pData[4:8]  
    64.             data = pData[8:]  
    65.         elif code_length == 127:  
    66.             masks = pData[10:14]  
    67.             data = pData[14:]  
    68.         else:  
    69.             masks = pData[2:6]  
    70.             data = pData[6:]  
    71.           
    72.         raw_str = ""  
    73.         i = 0  
    74.         for d in data:  
    75.             raw_str += chr(ord(d) ^ ord(masks[i%4]))  
    76.             i += 1  
    77.               
    78.         return raw_str  
    79.           
    80.           
    81. #打包发送数据给客户端  
    82. def SendData(pData,client):  
    83.     if(pData == False):  
    84.         return False  
    85.     else:  
    86.         pData = str(pData)  
    87.           
    88.     token = "\x81"  
    89.     length = len(pData)  
    90.     if length < 126:  
    91.         token += struct.pack("B", length)  
    92.     elif length <= 0xFFFF:  
    93.         token += struct.pack("!BH"126, length)  
    94.     else:  
    95.         token += struct.pack("!BQ"127, length)  
    96.     pData = '%s%s' % (token,pData)  
    97.   
    98.     client.send(pData)  
    99.       
    100.     return True  
    101.   
    102.   
    103. #这算是客户端一个循环接受数据并且处理数据的线程  
    104. def DoRemoteCommand(connection):  
    105.     while 1:  
    106.         szBuf = RecvData(8196,connection)  
    107.         if(szBuf == False):  
    108.             break  
     

    对,完了,就这样,启动

    Python代码  收藏代码
    1. InitWebSocketServer()  

    然后就可以与chrome和firefox的websocket通信了

    客户端的实现可以看我另一篇文章

    代码拿来直接就能用,在做项目中,没有这么多时间去系统的学习,有现成的资源就拿去用吧,以上代码实现的是新版的websocket协议,不兼容旧版的,目前网上大部分都是旧版的例子,需要的去找来组合下就可以了.

    上面代码只是个草稿,根据自己的情况进行修改,websocket目前只能传输字符串,图片传输等可以使用base64编码后进行发送(数据大小会增加 1/3 左右)

    博客地址:http://0x14.iteye.com/

  • 相关阅读:
    4网页版四则运算
    新的项目与小组成员
    课堂作业4月8号
    2.四则运算03
    zencart新增categories分类表字段步骤
    zencart批量评论插件Easy Populate CSV add reviews使用教程
    广告域名审核之后跳转技术:点击域名A页面iframe框架下的链接,域名A跳转到域名B
    zencart设置产品始终免运费sql
    zencart简易页面ezpage后台编辑位置
    php获取当前页面的完整url
  • 原文地址:https://www.cnblogs.com/lexus/p/2843351.html
Copyright © 2011-2022 走看看