我似乎找不到这里的问题。请帮忙。我想以 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"}
正如评论中提到的,您需要缓冲接收并提取完整的 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