使用python套接字发送json数据时出错

问题描述 投票:0回答:1

我似乎找不到这里的问题。请帮忙。我想以 json 格式包含每个单词并将其流式传输到服务器,服务器应将其流式传输到所有连接的客户端。它不会被传输到服务器或其他客户端。

这是我的客户端代码:

import socket
import json
import threading

# Define the server's IP address and port
SERVER_IP = '44.216.25.181'
SERVER_PORT = 55555

# Create a socket for the client
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((SERVER_IP, SERVER_PORT))

# Function to receive messages from the server
def receive_messages():
    while True:
        try:
            message = client_socket.recv(1024)
            if not message:
                break

            decoded_message = json.loads(message.decode())
            message_type = decoded_message.get('type')
            data = decoded_message.get('data')`
        
            
            if message_type == 'stream_text':
                # Handle streamed text
                print(f"Received streamed text: {data.get('chunk')}")

        except:
            break

# Start a thread to receive messages from the server
receive_thread = threading.Thread(target=receive_messages)
receive_thread.start()

# Example method for sending a JSON message to the server
def send_message(type, data):
    try:
        message = {'type': type, 'data': data}
        json_data = json.dumps(message)
        print(json_data)
        client_socket.send(json_data.encode())

    except Exception as e:
        print("e")
        print("Connection to the server is closed.")
        client_socket.close()
        
def printEvenLengthWords(s):
# splitting the words in a given string
words = s.split() # same as s.split(' ')
for word in words:
        print(word)
        send_message('stream_text', word)

# input string
user_input = input("Enter the text : ")

# calling the function
printEvenLengthWords(user_input)

这是我的服务器端代码:

import socket
import threading
import json

# Define the server's IP address and port
SERVER_IP = '0.0.0.0'
SERVER_PORT = 55555

# Create a socket for the server
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_IP, SERVER_PORT))
server_socket.listen()

# List to store connected clients
clients = []

# Function to broadcast messages to all connected clients
def broadcast(message):
    for client in clients:
        client.send(message)

# Function to handle client connections
def handle_client(client_socket):
    while True:
        try:
            # Receive data from the client
            message = client_socket.recv(1024)
            if not message:
                break

            # Decode the JSON message
            decoded_message = json.loads(message.decode())

            # Differentiate between message types
            message_type = decoded_message.get('type')
            data = decoded_message.get('data')

            if message_type == 'stream_text':
                # Handle streamed text
                generated_text = data.get('data')
                print(f"Received streamed text: {generated_text}")

                # Broadcast the streamed text to all clients
                chunk_size = 5
                chunks = [generated_text[i:i + chunk_size] for i in range(0, len(generated_text), chunk_size)]

                for chunk in chunks:
                    chunk_message = json.dumps({'type': 'stream_text', 'data': {'chunk': chunk}})
                    broadcast(chunk_message)
        except:
            # Remove the client from the list if there's an error or disconnection
            clients.remove(client_socket)
            client_socket.close()
            break

# Accept incoming connections and start a new thread for each client
while True:
    client_socket, client_address = server_socket.accept()
    clients.append(client_socket)
    client_thread = threading.Thread(target=handle_client, args=(client_socket,))
    client_thread.start()

当我同时运行客户端代码和服务器端时,我只看到这样的 json 输出:

$ python3 client1.py 
Enter the text : this is a test
this
{"type": "stream_text", "data": "this"}
is
{"type": "stream_text", "data": "is"}
a
{"type": "stream_text", "data": "a"}
test
{"type": "stream_text", "data": "test"}
python json sockets tcp streaming
1个回答
0
投票

正如评论中提到的,您需要缓冲接收并提取完整的 JSON 消息。下面是一个示例,它通过使用 socket.makefile

 将完整的 JSON 消息作为单独的换行符终止的文本行(
JSON Lines 格式)发送,通过将其包装在类似文件的对象中并使用其
 来缓冲套接字.readline()
方法:

服务器.py

import socket
import json

with socket.socket() as sock:
    sock.bind(('', 5000))
    sock.listen()
    while True:
        client, addr = sock.accept()
        print(f'{addr}: connected')
        # makefile wraps a socket in a file-like object for buffering
        with client, client.makefile('r', encoding='utf8') as infile:
            while True:
                # Extract a line containing JSON
                line = infile.readline()
                if not line: break
                print(f'{addr}: {json.loads(line)}')
        print(f'{addr}: disconnected')

客户端.py

import socket
import json

def send(sock, data):
    # Send JSON without `indent` parameter so it is a single line.
    # Terminate with a newline for the makefile wrapper in server.
    encoded = json.dumps(data).encode() + b'\n'
    sock.sendall(encoded)

with socket.socket() as sock:
    sock.connect(('localhost', 5000))
    send(sock, {'type': 'whatever', 'data': 'something'})
    send(sock, {'type': 'withnewlines', 'data': 'abc\ndef\nghi\n'})
    send(sock, {'type': 'example', 'data': 123.456})

运行服务器,然后运行客户端几次:

('127.0.0.1', 10320): connected
('127.0.0.1', 10320): {'type': 'whatever', 'data': 'something'}
('127.0.0.1', 10320): {'type': 'withnewlines', 'data': 'abc\ndef\nghi\n'}
('127.0.0.1', 10320): {'type': 'example', 'data': 123.456}
('127.0.0.1', 10320): disconnected
('127.0.0.1', 10321): connected
('127.0.0.1', 10321): {'type': 'whatever', 'data': 'something'}
('127.0.0.1', 10321): {'type': 'withnewlines', 'data': 'abc\ndef\nghi\n'}
('127.0.0.1', 10321): {'type': 'example', 'data': 123.456}
('127.0.0.1', 10321): disconnected
© www.soinside.com 2019 - 2024. All rights reserved.