html5 websocket 新版协议聊天室 服务端(python版)

本文分享了一段基于新版WebSocket协议编写的服务端代码,并详细解释了握手协议及字符发送接收方式的变化。通过具体实例帮助读者理解新版协议下WebSocket服务端的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上找了很多代码都是旧版协议的,研究了很久终于弄清楚了 现在发个用新版协议写的服务端代码出来(这个代码是从网上旧版协议改过来的)
最要就是握手协议和发送接受字符的方式变了

# incoding=utf-8
import socket
import struct
import hashlib
import threading,random
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

connectionlist = {}

def sendMessage(message):
    global connectionlist
    for connection in connectionlist.values():
        print connection
        bstr = send_data(message)
        print bstr
        b = connection.send(bstr)

def deleteconnection(item):
    global connectionlist
    del connectionlist['connection'+item]

#接收客户端发送过来的消息,并且解包
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 send_data(raw_str):
    back_str = []

    back_str.append('\x81')
    data_length = len(raw_str)

    if data_length < 125:
        back_str.append(chr(data_length))
    else:
        back_str.append(chr(126))
        back_str.append(chr(data_length >> 8))
        back_str.append(chr(data_length & 0xFF))

    back_str = "".join(back_str) + raw_str    
    return back_str
     
class WebSocket(threading.Thread):
    def __init__(self,conn,index,name,remote, path="/"):
        threading.Thread.__init__(self)
        self.conn = conn
        self.index = index
        self.name = name
        self.remote = remote
        self.path = path
        self.buffer = ""
        
    def run(self):
        print 'Socket%s Start!' % self.index
        headers = {}
        self.handshaken = False

        while True:
            if self.handshaken == False:
                print 'Socket%s Start Handshaken with %s!' % (self.index,self.remote)
                self.buffer += self.conn.recv(1024)
                if self.buffer.find('\r\n\r\n') != -1:
                    header, data = self.buffer.split('\r\n\r\n', 1)
                    for line in header.split("\r\n")[1:]:
                        key, value = line.split(": ", 1)
                        headers[key] = value
                    print 'header:-->'+header
                    headers["Location"] = "ws://%s%s" %(headers["Host"], self.path)
                    self.buffer = data[8:]
                    key = headers["Sec-WebSocket-Key"]
                    token = self.generate_token(key)
                    
                    handshake = '\
HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
Upgrade: webSocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Accept:%s\r\n\
Sec-WebSocket-Origin: %s\r\n\
Sec-WebSocket-Location: %s\r\n\r\n\
' %(token,headers['Origin'], headers['Location'])

                    print handshake
                    num = self.conn.send(handshake)
                    print str(num)
                    self.handshaken = True
                    print 'Socket%s Handshaken with %s success!' % (self.index,self.remote)
                    #self.conn.send('\x00'+'Welcome'+'\xFF'+'\n')
                    bstr = send_data("Welcome")
                    print bstr
                    self.conn.send(bstr)
                    #SendData('\x00'+'Welcome'+'\xFF',self.conn)
                    #sendMessage('Welcome, '+self.name+' !')
            else:
                self.buffer = RecvData(8196,self.conn)                
                if self.buffer:
                    print 'rec:'+self.buffer                   
                if self.buffer:
                    #s = self.buffer.split("\xFF")[0][1:]
                    s = self.buffer
                    if s=='quit':
                        print 'Socket%s Logout!' % (self.index)
                        sendMessage(self.name+' Logout')
                        deleteconnection(str(self.index))
                        self.conn.close()
                        break
                    else:
                        print 'Socket%s Got msg:%s from %s!' % (self.index,s,self.remote)
                        sendMessage(self.name+':'+s)
                    self.buffer = ""
    
    def generate_token(self, key):
        import base64
        nkey=key+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
        nkey=base64.b64encode(hashlib.sha1(nkey).digest())
        return nkey

class WebSocketServer(object):
    def __init__(self):
        self.socket = None
    def begin(self):
        print 'WebSocketServer Start!'
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.bind(("192.168.1.210",1234))
        self.socket.listen(50)
        
        global connectionlist
        
        i=0
        while True:
            connection, address = self.socket.accept()
            username=address[0]
            newSocket = WebSocket(connection,i,username,address)
            newSocket.start()
            connectionlist['connection'+str(i)]=connection
            i = i + 1

if __name__ == "__main__":
    server = WebSocketServer()
    server.begin()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值