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

t3irkdon  于 12个月前  发布在  Python
关注(0)|答案(1)|浏览(130)

我似乎找不到这里的问题.请帮助.我想包括每个单词在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"}

rlcwz9us

rlcwz9us1#

正如在注解中提到的,你需要缓冲接收和提取完整的JSON消息。下面是一个例子,通过使用socket.makefile将套接字 Package 在一个类似文件的对象中并使用其.readline()方法来缓冲套接字,将完整的JSON消息作为单独的以换行符结尾的文本行(JSON Lines)发送:
server.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')

字符串
client.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

相关问题