python 套接字编程中未显示一个输出

One Output is not showing in python socket programming

我正在编写一个简单的 python 套接字程序,其中客户端向服务器发送一个字符串,服务器说出该字符串中有多少个元音字母,然后将其发送回客户端,客户端打印输出。现在,我不知道为什么在发送 end 消息后没有显示 connection ended 。如果我从那里删除 \n ,除了 MESSAGE RECEIVED 出现在 Not enough vowel 之后的下一行之外,所有消息都出现在同一行中。现在我如何显示 CONNECTION ENDED 同时将所有消息保持在单独的行中。

server.py

import socket
FORMAT = 'utf-8'
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST,PORT)
DISCONNECTED_MESSAGE = 'End'

server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(ADDR)
server.listen()
print("[LISTENING] server is listenning")


while True:
    conn,addr = server.accept()
    connected = True
    while connected:
        msg = conn.recv(2048).decode(FORMAT)
        if msg == DISCONNECTED_MESSAGE:
            connected = False
            conn.send("CONNECTION ENDED".encode(FORMAT))
        else:
            vowel_count = 0
            for chr in msg:
                if chr in "aeiouAEIOU":
                    vowel_count += 1
            if vowel_count == 0:
                conn.send("Not enough vowels".encode(FORMAT))
            elif vowel_count <= 2:
                conn.send("Enough Vowel I guess\n".encode(FORMAT))
            else:
                conn.send("Too many vowels\n".encode(FORMAT))
            
            conn.send("MESSAGE RECEIVED\n".encode(FORMAT))

conn.close() 

client.py

import socket

PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST,PORT)
FORMAT = 'utf-8'
DISCONNECTED_MESSAGE = 'End'
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(ADDR)

def send(msg):
    message =  msg.encode(FORMAT)
    client.send(message)
    print(client.recv(2048).decode(FORMAT))
    


send("Nymphs cry gypsy rhythms Why Mythy nymphs cry ?Why nymphs flyby ?")
send("Nymphs cry gypsy rhythms hello Why Mythy nymphs cry ?Why nymphs flyby ?")
send("Nymphs cry gypsy rhythms Why Mythy nymphs cry ?Why nymphs flyby ? hello hello everybody good evening")
send(DISCONNECTED_MESSAGE)

这里的问题是TCP是流协议,不是包协议。 reader 不会在您编写的同一块中获取内容。在您的特定情况下,您的服务器为每个输入发送两个响应(元音数量和“收到的消息”)。有时,这两条消息打包在一起,并在一次读取中被客户端接收,但有时,您只读取元音评估本身。然后您的客户端 send 运行 returns,并发送下一条消息。然后它会显示“收到的消息”,即使那些服务器已经排队多了两行。当它到达终点时,即使“CONNECTION ENDED”仍在排队,它也会退出。

真正的解决方案是让您的服务器在传输完成时发送一些“传输结束”信号,例如一些未使用的控制字符。然后您的客户端应该继续阅读,直到它得到一个以您的“传输结束”信号结尾的字符串。

短期修复只是让您的服务器将它要发送的所有字符串连接到一个 conn.send 调用中。从技术上讲,允许 TCP 将其分成更小的块进行传输,因此它仍然可能会失败,但实际上不会发生这种情况。