Протокол WebSocket (RFC 6455). Фрагментированное сообщение не имеет бита FIN и заголовков.Python

Программы на Python
Ответить
Anonymous
 Протокол WebSocket (RFC 6455). Фрагментированное сообщение не имеет бита FIN и заголовков.

Сообщение Anonymous »

Я пытаюсь проанализировать сообщение в рамке веб-сокета с помощью RFC6455 и заметил, что только первый кадр имеет заголовок, а последующие - нет.
Я решил эту проблему, используя payload_length, но он не работает с двоичные сообщения.
Я отправляю сообщение размером 5 МБ и получаю все 5 МБ через сокет TCP, но payload_length = 131000.
Я не знаю, что делать сделать...
Как определить, что сообщение доставлено на сервер полностью

Код: Выделить всё

import socket
import hashlib
import base64
import struct

import signal
import sys

Frame_Mode = False

Full_Package_Size = 0
Got_Data = 0

Full_Package = b""

def generate_websocket_key(key):
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
hash_value = hashlib.sha1(key.encode() + GUID.encode()).digest()
return base64.b64encode(hash_value).decode()

def Parse():
#opcode = Full_Package[0] & 0x0F
masked = (Full_Package[1] & 0x80) >> 7
payload_length = Full_Package[1] & 0x7F

if payload_length == 126:
payload_length = struct.unpack('!H', Full_Package[2:4])[0]
offset = 4
elif payload_length == 127:
payload_length = struct.unpack('!Q', Full_Package[2:10])[0]
offset = 10
else:
offset = 2

#print(payload_length)

if masked:
masking_key = Full_Package[offset:offset+4]
offset += 4
payload = bytearray()
for i in range(payload_length):
payload.append(Full_Package[offset + i] ^ masking_key[i % 4])
else:
payload = Full_Package[offset:offset+payload_length]

print(len(payload))

def parse_websocket_frame(data):
global Frame_Mode, Full_Package_Size, Got_Data, Full_Package, PC

u_data = data[:2]
#print(u_data)
head1, head2 = struct.unpack("BB", u_data) #bytearray(b'\xc1\xab')
fin = (data[0] & 0b10000000)

opcode_byte = (data[0] & 0b00001111).to_bytes(1, byteorder='big')

Got_Data += len(data)
print(f"fin: {fin} opcode: {opcode_byte} len: {Got_Data}")
#print(u_data)

payload_length = data[1] & 0x7F

masked = (data[1] & 0x80) >>  7

if payload_length == 126:
payload_length = struct.unpack('!H', data[2:4])[0]
offset = 4
elif payload_length == 127:
payload_length = struct.unpack('!Q', data[2:10])[0]
offset = 10
else:
offset = 2

if masked:
offset += 4

def handle_client(client_socket):
request = client_socket.recv(1024).decode('utf-8')
print("Received request:\n", request)

headers = request.split('\r\n')
websocket_key = ""
for header in headers:
if header.startswith("Sec-WebSocket-Key:"):
websocket_key = header.split(":")[1].strip()

if websocket_key:
accept_key = generate_websocket_key(websocket_key)
response = (
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
f"Sec-WebSocket-Accept: {accept_key}\r\n"
"\r\n"
)
client_socket.send(response.encode('utf-8'))
print("Handshake completed")

while True:
data = client_socket.recv(1024)
#print(len(data))
#print("\n")
if not data:
print("Empty Package")
#break
message = parse_websocket_frame(data)
#print(f"Received message: {message}")
#print("\n")

client_socket.close()

def signal_handler(sig, frame, server_socket):
print('Program terminated by user')
server_socket.close()
sys.exit(0)

def main():

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('localhost', 56000))
server_socket.listen(5)
print("Server listening on port 56000")

signal.signal(signal.SIGINT, lambda sig, frame: signal_handler(sig, frame, server_socket))

while True:
client_socket, addr = server_socket.accept()
print(f"Accepted connection from {addr}")
handle_client(client_socket)

if __name__ == "__main__":
main()
Я пытался перевернуть код библиотеки Websockets, но для меня это слишком сложно, я разработчик C++. Используйте Python только для свойств отладки.


Подробнее здесь: https://stackoverflow.com/questions/792 ... nd-headers
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»