问题是:print()
client()
只输出一行,而我希望它打印几行,因为它所驻留的while
循环显然运行了多次。
当我测试 Python网络编程基础,第3版 一书中给出的示例代码时,会出现问题。此示例代码基本上创建了一个简单的TCP服务器/客户端,用于处理/发送简单的文本大写请求。以下是代码:
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter03/tcp_deadlock.py
# TCP client and server that leave too much data waiting
import argparse, socket, sys
def server(host, port, bytecount):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, port))
sock.listen(1)
print('Listening at', sock.getsockname())
while True:
sc, sockname = sock.accept()
print('Processing up to 1024 bytes at a time from', sockname)
n = 0
while True:
data = sc.recv(1024)
if not data:
break
output = data.decode('ascii').upper().encode('ascii')
sc.sendall(output) # send it back uppercase
n += len(data)
print('\r %d bytes processed so far' % (n,), end=' ')
sys.stdout.flush()
print()
sc.close()
print(' Socket closed')
def client(host, port, bytecount):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
bytecount = (bytecount + 15) // 15 * 16 # round up to a multiple of 16
message = b'CAP!' # 16-byte message to repeat over and over
print('Sending', bytecount, 'bytes of data, in chunks of 16 bytes')
sock.connect((host, port))
sent = 0
while sent < bytecount:
sock.sendall(message)
sent += len(message)
# print('test')
print('\r %d bytes sent' %(sent,), end=' ') # <-- THIS IS THE PROBLEMATIC PRINT()
sys.stdout.flush()
print()
sock.shutdown(socket.SHUT_WR)
print('Receiving all the data the server sends back')
received = 0
while True:
data = sock.recv(42)
if not received:
print(' The first data received says', repr(data))
if not data:
break
received += len(data)
print('\r %d bytes received' %(received,), end=' ')
print()
sock.close()
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Get deadlocked over TCP')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('host', help='interface the server listens at;'
' host the client sends to')
parser.add_argument('bytecount', type=int, nargs='?', default=16,
help='number of bytes for client to send (default 16)')
parser.add_argument('-p', metavar='PORT', type=int, default=1060,
help='TCP port (default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.host, args.p, args.bytecount)
在我本地创建服务器之后,我用
启动了我的客户端python listing3-2.py client 0.0.0.0
这是我得到的输出:
发送32个字节的数据,以16个字节的块为单位 发送了32个字节
接收服务器发回的所有数据收到的第一个数据 b&#39; CAP!CAP!CAP!CAP!CAP!CAP!CAP!CAP!&#39;收到32个字节
从此输出中我们知道while()
循环已运行8次(因为8&#39; CAP!&#39; s)但print('\r %d bytes sent' %(sent,), end=' ')
仅运行一次。对我来说更奇怪的是sys.stdout.flush()
无法工作,尽管作者可能也注意到了这个问题。
当我在有问题的print('test')
之前尝试添加一行print()
时会发生更奇怪的事情,看看会发生什么?
python listing3-2.py client 0.0.0.0
发送32个字节的数据,以16字节的块为单位进行测试 4个字节发送测试 8个字节发送测试
12个字节发送测试
16个字节发送测试
20个字节发送测试
24字节发送测试 28个字节发送测试
发送了32个字节 接收服务器发回的所有数据收到的第一个数据说 B&#39;!!!!!!!!CAP CAP CAP CAP CAP CAP CAP CAP&#39;收到32个字节
在之前有一个额外的print()
,print('\r %d bytes sent' %(sent,), end=' ')
运行8次,尽管循环结构完全没有变化。我完全感到困惑的是,添加print()
会带来这样的后果。而且,如果在这种情况下使用print()
方法可能会有一些奇怪的特征,我也会感到困惑。
答案 0 :(得分:1)
打印邮件中的\r
与end=' '
相结合。这是一个没有换行的回车,所以所有的线都相互打印。额外的print
添加换行符,它们会停止相互打印。将其更改为\n
以进行修复,或更简单地说:
print(sent,'bytes sent')
P.S。还有一个数学错误:
bytecount = (bytecount + 15) // 15 * 16
应该是:
bytecount = (bytecount + 15) // 16 * 16