Python socket.recv() 返回新行?

Posted

技术标签:

【中文标题】Python socket.recv() 返回新行?【英文标题】:Python socket.recv() returning new lines? 【发布时间】:2021-05-26 13:27:18 【问题描述】:

我对 Python 还很陌生。我有两个正在运行的脚本相互通信,但是一旦发送方进程停止发送字节,接收方进程就会收到无穷无尽的解码(UTF-8)到新行的流。为了简单起见,我尽可能地减少了代码:

发送 Python 脚本。

import socket

s = socket.socket()
host = "127.0.0.1"
port = 5409
s.bind((host, port))

data_to_send = ['1','2','3','4','5','6','7','8','9']

s.listen(1)
c, addr = s.accept()
print ('Got connection from ', addr,'. Sending data...', sep='')
for data in data_to_send:
   message = data.encode('utf-8')
   c.sendall(message)

接收器 Python 脚本。

import socket

messages_received = 0
s = socket.socket()         
host = "127.0.0.1"         
port = 5409                 

s.connect((host, port))
while True:
    incoming_message = s.recv(1024).decode('utf-8')
    messages_received += 1
    
    # This condition is just to avoid printing thousands of lines
    if messages_received < 10:
        print(messages_received, ':', incoming_message)

接收器输出。

1 : 1
2 : 23456789
3 : 
4 :
5 :
6 :
7 :
8 :
9 :

我做错了什么?理想情况下,如果套接字关闭,我希望发送者脚本能够跳出“While True”循环。

【问题讨论】:

当然它不会跳出循环——你还没有定义任何导致循环结束的条件。添加为循环的第二行:if not incoming_message: break. 我认为即使发件人尚未发送更多消息(例如,发送第一条消息,稍等,发送第二条消息,我认为接收者不会),这也会导致接收者收到空白消息t 收到第二个)但我已经在发送方进行了快速测试,但它可以工作。感谢您及时的回复!作为一个附带问题,您能告诉我为什么接收者会无休止地收到所有空白消息吗? 发送方关闭套接字后,接收方除了一条空白消息还能返回什么?没完没了只是因为你在收到第一条空白消息后又错误地调用了.recv() 我无法收到任何东西(只会一直等待)或引发异常 【参考方案1】:

正如@jasonharper 指出的那样,我需要做的就是检查空消息并在发生这种情况时立即中断循环。当发送者不发送任何东西时,接收者不会收到空消息,它只是等待一个有效的消息,我不知道。以下代码对我有用:

发送 Python 脚本。

import socket
import time

s = socket.socket()
host = "127.0.0.1"
port = 5409
s.bind((host, port))

data_to_send = ['1','2','3','4','5','6','7','8','9']

s.listen(1)
c, addr = s.accept()
print ('Got connection from ', addr,'. Sending data...', sep='')
for data in data_to_send:
    message = data.encode('utf-8')
    c.sendall(message)
    time.sleep(1)

接收器 Python 脚本。

import socket

messages_received = 0
s = socket.socket()         
host = "127.0.0.1"         
port = 5409                 

s.connect((host, port))
while True:
    incoming_message = s.recv(1024).decode('utf-8')
    messages_received += 1

    
    if not incoming_message:
        break
    if messages_received < 10:
        print(messages_received, ':', incoming_message)

接收器输出。

1 : 1
2 : 2
3 : 3
4 : 4
5 : 5
6 : 6
7 : 7
8 : 8
9 : 9

【讨论】:

【参考方案2】:

您可以尝试在发送方设置缓冲区大小: socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024) # 缓冲区大小 1024

如果它不起作用,您甚至可以尝试使用 dict 格式,以便以 json 格式发送数据。

【讨论】:

我看不出这有什么帮助,因为显然缓冲区没有问题(发送了整个消息)。我不知道发送字典会将其编码为 JSON,这很好知道!

以上是关于Python socket.recv() 返回新行?的主要内容,如果未能解决你的问题,请参考以下文章

如何判断对端关闭了socket

在Python3中,socket.recv方法如果一段时间内没有收到返回,如何让这段代码跳过,并执行下一步操作

python3.6:socket.recv() 与 socket.recv_into() 性能对比

C++ Socket recv() 总是返回 0

Python实现简单Web服务器

为啥 sys socket recv 函数不填充数据但返回字节长度?