LINUX.ORG.RU

Помогите исправить код под Python3

 , , ,


0

3

Смог только исправить соединении, но ответ от сервера по прежнему не работает.

Типы данных исправлял так:
Python: | Python 3:
u"test" | «test»
«test» | b"test"

#!/usr/bin/python
# -*- coding:utf-8 -*-

from select import select
from threading import Thread
import time, struct, socket, hashlib, base64, sys, signal

MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
TEXT = 0x01
BINARY = 0x02
 
class WebSocket(object):
 
    handshake = (
        "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
        "Upgrade: WebSocket\r\n"
        "Connection: Upgrade\r\n"
        "Sec-WebSocket-Accept: %(key)s\r\n"
        "\r\n"
    )
 
    def __init__(self, client, server):
        self.client = client
        self.server = server
        self.handshaken = False
        self.header = ""
 
    def feed(self, data):
        if not self.handshaken:
            self.header += data
            if self.header.find('\r\n\r\n') != -1:
                parts = self.header.split('\r\n\r\n', 1)
                self.header = parts[0]
                if self.dohandshake(self.header, parts[1]):
                    self.handshaken = True
        else:
            recv = self.decodeCharArray(data)
            self.onmessage(''.join(recv).strip())
 
    def sendMessage(self, s):
        message = ""
        b1 = 0x80
 
        if type(s) == unicode:
            b1 |= TEXT
            payload = s.encode("UTF8")
        elif type(s) == str:
            b1 |= TEXT
            payload = s
 
        message += chr(b1)
 
        b2 = 0
        
        length = len(payload)
        
        if length < 126:
            b2 |= length
            message += chr(b2)
        elif length < (2 ** 16) - 1:
            b2 |= 126
            message += chr(b2)
            l = struct.pack(">H", length)
            message += l
        else:
            l = struct.pack(">Q", length)
            b2 |= 127
            message += chr(b2)
            message += l
 
        message += payload
 
        self.client.send(str(message))
 
    def decodeCharArray(self, stringStreamIn):
        byteArray = [ord(character) for character in stringStreamIn]
        datalength = byteArray[1] & 127
        indexFirstMask = 2
 
        if datalength == 126:
            indexFirstMask = 4
        elif datalength == 127:
            indexFirstMask = 10
 
        masks = [m for m in byteArray[indexFirstMask : indexFirstMask+4]]
        indexFirstDataByte = indexFirstMask + 4
        
        decodedChars = []
        i = indexFirstDataByte
        j = 0
        
        while i < len(byteArray):
            decodedChars.append( chr(byteArray[i] ^ masks[j % 4]) )
            i += 1
            j += 1
 
        return decodedChars
 
    def dohandshake(self, header, key=None):
        handshake = self.handshake
        
        for line in header.split('\r\n')[1:]:
            name, value = line.split(': ', 1)
            
            if name.lower() == "sec-websocket-key":
                combined = value + MAGIC_GUID
                key = base64.b64encode(hashlib.sha1(combined).digest())
                
                handshake = handshake % { 'key' : key }
 
        self.client.send(handshake)
        return True
 
    def onmessage(self, data):
        self.sendMessage(data.upper());
 
    def send(self, data):
        self.client.send(chr(0) + data + chr(255))
 
    def close(self):
        self.client.close()
 

class WebSocketServer(object):
 
    def __init__(self, bind, port, cls):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind((bind, port))
        self.bind = bind
        self.port = port
        self.cls = cls
        self.connections = {}
        self.listeners = [self.socket]
 
    def listen(self, backlog=5):
 
        self.socket.listen(backlog)
 
        self.running = True
        while self.running:
        
            rList, wList, xList = select(self.listeners, [], self.listeners, 1)
            for ready in rList:
                if ready == self.socket:
                    client, address = self.socket.accept()
                    fileno = client.fileno()
                    self.listeners.append(fileno)
                    self.connections[fileno] = self.cls(client, self)
                else:
                    client = self.connections[ready].client
                    data = client.recv(4096)
                    fileno = client.fileno()
                    if data:
                        self.connections[fileno].feed(data)
                    else:
                        self.connections[fileno].close()
                        del self.connections[fileno]
                        self.listeners.remove(ready)
            
            for failed in xList:
                if failed == self.socket:
                    for fileno, conn in self.connections:
                        conn.close()
                    self.running = False
 
if __name__ == "__main__":
    server = WebSocketServer("", 8000, WebSocket)
    server_thread = Thread(target=server.listen, args=[5])
    server_thread.start()
 
    def signal_handler(signal, frame):
        server.running = False
        sys.exit()
    signal.signal(signal.SIGINT, signal_handler)
 
    while True:
        time.sleep(100)

Для питона есть дебагер, однако. Сам дебажить пробовал?

Cactus64k ()
Ответ на: комментарий от Cactus64k

Код выполняется без ошибок. Ошибка в кодирование даных, которые отдает сервер. В начало сообщения добавляется лишний символ с кодом 194

iYaroslav ()

глаза потекли.

ты это.

не делай ТАК,

qulinxao ★★☆ ()
Ответ на: комментарий от iYaroslav

Причем тут с ошибками или без. У твоей простыни с логикой трабла. Погляди из под отладчика что именно пересылается.

Cactus64k ()

Дополни каждую функцию отправки сообщения отладкой. Замени к примеру:

self.client.send(str(message))
на
print('№x "%s"' % (str(message)))
self.client.send(str(message))

  • №x - тут поставь уникальные номера
  • str(message) - все содержимое функции отправки данных send.

По результатам эксперимента ответь, в которой из строчек у тебя данные с лишним байтом отправляются серверу.

anonymous ()
Ответ на: комментарий от anonymous

Зачем костыли с принтом, если есть нормальный дебагер?

Cactus64k ()

#!/usr/bin/python

Лучше так:

#!/usr/bin/env python3
sT331h0rs3 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.