Я решил эту проблему, используя 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()
Подробнее здесь: https://stackoverflow.com/questions/792 ... nd-headers
Мобильная версия