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  
import socket,threading,struct

#启动websocket server
def InitWebSocketServer():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.bind(("localhost",3398)) #绑定本地地址,端口3398
        sock.listen(100)
    except:
        print("Server is already running,quit")
        sys.exit()
    while True:  #创建一个死循环,接受客户端
        connection,address = sock.accept()
        if(handshake(connection) != False): #如果握手失败,不启动任务
            t = threading.Thread(target=DoRemoteCommand,args=(connection,))
            t.start()


#连接成功后回应给客户端进行握手
def handshake(client):
    headers = {}
    shake = client.recv(1024)
    
    if not len(shake):
        return False
    
    header, data = shake.split('\r\n\r\n', 1)
    for line in header.split("\r\n")[1:]:
        key, value = line.split(": ", 1)
        headers[key] = value
    
    if(headers.has_key("Sec-WebSocket-Key") == False):
        print("this socket is not websocket,close")
        client.close()
        return False
    
    szOrigin = headers["Sec-WebSocket-Origin"]
    szKey = base64.b64encode(hashlib.sha1(headers["Sec-WebSocket-Key"] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())
    szHost = headers["Host"]
    
    our_handshake = "HTTP/1.1 101 Switching Protocols\r\n" \
                    "Upgrade:websocket\r\n"\
                    "Connection: Upgrade\r\n"\
                    "Sec-WebSocket-Accept:"+ szKey + "\r\n" \
                    "WebSocket-Origin:" + szOrigin + "\r\n" \
                    "WebSocket-Location: ws://" + szHost + "/WebManagerSocket\r\n" \
                    "WebSocket-Protocol:WebManagerSocket\r\n\r\n"
                    
    client.send(our_handshake)
    return True

#接收客户端发送过来的消息,并且解包
def RecvData(nNum,client):
    try:
        pData = client.recv(nNum)
        if not len(pData):
            return False
    except:
        return False
    else:
        code_length = ord(pData[1]) & 127
        if code_length == 126:
            masks = pData[4:8]
            data = pData[8:]
        elif code_length == 127:
            masks = pData[10:14]
            data = pData[14:]
        else:
            masks = pData[2:6]
            data = pData[6:]
        
        raw_str = ""
        i = 0
        for d in data:
            raw_str += chr(ord(d) ^ ord(masks[i%4]))
            i += 1
            
        return raw_str
        
        
#打包发送数据给客户端
def SendData(pData,client):
    if(pData == False):
        return False
    else:
        pData = str(pData)
        
    token = "\x81"
    length = len(pData)
    if length < 126:
        token += struct.pack("B", length)
    elif length <= 0xFFFF:
        token += struct.pack("!BH", 126, length)
    else:
        token += struct.pack("!BQ", 127, length)
    pData = '%s%s' % (token,pData)

    client.send(pData)
    
    return True


#这算是客户端一个循环接受数据并且处理数据的线程
def DoRemoteCommand(connection):
    while 1:
        szBuf = RecvData(8196,connection)
        if(szBuf == False):
            break


 

 

对,完了,就这样,启动

 

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

 

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

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

 

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

 

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

 

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

posted on 2013-01-03 21:04  lexus 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lexus/archive/2013/01/03/2843351.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket Server是一种用于实时通信的协议,而Python提供了一些库和框架来创建和管理WebSocket服务器。一个常见的Python库是"python-websocket-server",你可以在这个GitHub链接中找到它的代码。 关于如何创建WebSocket服务器的示例代码如下所示: ``` #coding:utf-8 from lib.socket.websocket_server import WebsocketServer def startWebsocketServer(): def new_client(client, server): server.send_message_to_all("Hey all, a new client has joined us") def mysend(client,server,msg): print(msg) server.send_message(client,"哈哈哈哈哈") if(msg == "_end"): #如果收到了_end消息,那么断开连接 server.server_close() server = WebsocketServer(5005, host='127.0.0.1', loglevel=logging.INFO) server.set_fn_new_client(new_client) server.set_fn_message_received(mysend) server.run_forever() server.server_close() if __name__ == "__main__": startWebsocketServer() ``` 这个代码片段展示了如何使用"python-websocket-server"库创建一个WebSocket服务器。在这个示例中,服务器将在本地主机上的端口5005上运行。当有新客户端连接时,服务器会向所有客户端发送一条消息。同时,服务器还定义了一个名为"mysend"的回调函数,用于处理从客户端接收到的消息并发送回复。如果接收到的消息是"_end",服务器将关闭连接。 这只是一个基本的示例,你可以根据自己的需求进行修改和扩展。希望这个回答对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值