跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 求 Python 大佬解救
未分類
9 11 月 2020

求 Python 大佬解救

求 Python 大佬解救

資深大佬 : 1521815837 0

最近做项目写了一个小 websocket 服务器但是有报错我自己没法搞定求大神解救

报错信息: 求 Python 大佬解救 代码:

import socket import time import hashlib import base64 import struct import threading import chardet  connlist = [] s = socket.socket()          host = "0.0.0.0" port = 1999                 s.bind((host, port))        s.listen(500)   def getheads(data):     data = data.decode()     datasplit = data.split("rn")     datasplit = datasplit[1:-2]     headslist = {}     for i in datasplit:         k,v = i.split(":",1)         headslist[k] = v.replace(' ','')     return headslist  def _get_data(info, setcode):     payload_len = info[1] & 127     fin = 1 if info[0] & 128 == 128 else 0     opcode = info[0] & 15     if payload_len == 126:         mask = info[4:8]         decoded = info[8:]     elif payload_len == 127:         mask = info[10:14]         decoded = info[14:]     else:         mask = info[2:6]         decoded = info[6:]     bytes_list = bytearray()     for i in range(len(decoded)):         chunk = decoded[i] ^ mask[i % 4]         bytes_list.append(chunk)     if opcode == 0x00:         opcode = setcode     if opcode == 0x01:         body = str(bytes_list, encoding='utf-8',errors='ignore')         return fin, opcode, body     else:         body = decoded         return fin, opcode, body              def recv(conn):     msg = ''     opcode = 0x00     while True:         raw_data = b''         while True:             section = conn.recv(1024)             raw_data += section             if len(section) < 1024:                 break         fin, _opcode, fragment = _get_data(raw_data,opcode)         opcode = _opcode if _opcode != 0x00 else opcode         msg += fragment         if fin == 1:              break     return msg      def send(conn,msg,fin=True):     data = struct.pack('B', 129) if fin else struct.pack('B', 0)     msg_len = len(msg)     if msg_len <= 125:         data += struct.pack('B', msg_len)     elif msg_len <= (2**16 - 1):         data += struct.pack('!BH', 126, msg_len)     elif msg_len <= (2**64 - 1):         data += struct.pack('!BQ', 127, msg_len)     else:         while True:             fragment = msg[:(2**64 - 1)]             msg -= fragment             if msg > (2**64 - 1):                 conn.send(fragment, False)             else:                 conn.send(fragment)     data += bytes(msg,encoding='utf-8',errors='ignore')     conn.send(data)   def shakehands(conn):     data = conn.recv(1024)     heads = getheads(data)     msg = heads["Sec-WebSocket-Key"]     key = msg + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'     ser_key = hashlib.sha1(key.encode('utf-8')).digest()     token = base64.b64encode(ser_key)     message = "HTTP/1.1 101 Switching ProtocolsrnUpgrade: websocketrnConnection: UpgradernSec-WebSocket-Accept: "+bytes.decode(token)+"rnWebSocket-Origin: "+str(heads["Origin"])+"rnWebSocket-Location: ws://"+str(heads["Host"])+"rnrn"     conn.send(message.encode())     connlist.append(conn)  def websockethandle(conn,addr):     shakehands(conn)      ip,port = addr     print(ip+" 连入")     print("当前用户数:"+str(len(connlist)))     while True:         try:              data= recv(conn)         except Exception as e:             print(e)             print(ip+" 断开")             conn.close()             connlist.remove(conn)             print("当前用户数:"+str(len(connlist)))             break         for i in connlist:             if i != conn:                 send(i,data)                      while True:     conn,addr = s.accept()     threading.Thread(target=websockethandle,args=(conn,addr,)).start() 

大佬有話說 (8)

  • 資深大佬 : anjianshi

    排查一下所有 + 号的地方?是不是在把字符串和 bytes 进行拼接。
    并且看错误信息,是左侧字符串,右侧 bytes 。例如
    a = ‘abc’
    b = b’def’
    a + b
    会报这个

  • 資深大佬 : anjianshi

    粗看了一下,你看是不是这样的问题:
    1. def recv(conn) 里调用 _get_data(raw_data) 时传入的 raw_data 是 bytes
    2. def _get_data(info, setcode) 里收到的 info 是 bytes,函数里的 decoded 变量是基于 info 的,所以也是 bytes,
    然后函数返回值 body 在最下面的一个 if 分支,就等于 decoded 变量,所以返回的也是 bytes
    3. def recv(conn) 获取到 _get_data() 的返回值并写入 fragment 变量,但按上面的流程,fragment 是一个 bytes
    4. def recv(conn) 执行了 msg += fragment,msg 是 str,fragment 是 bytes,最终报错

  • 資深大佬 : dd99iii

    message = “HTTP/1.1 101 Switching ProtocolsrnUpgrade: websocketrnConnection: UpgradernSec-WebSocket-Accept: “+bytes.decode(token)+”rnWebSocket-Origin: “+str(heads[“Origin”])+”rnWebSocket-Location: ws://”+str(heads[“Host”])+”rnrn”

    我猜这个是 bytes:
    bytes.decode(token)

  • 資深大佬 : dd99iii

    @dd99iii 猜错了

  • 資深大佬 : CEBBCAT

    明白了吗?#为什么而活?

  • 資深大佬 : ysc3839

    “客户端断开连接”是在哪出现的?你的代码里没有呀?

  • 資深大佬 : qile1

    msg=b”试试

  • 資深大佬 : dahuahua

    为什么不打印日志

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具