shi*_*iva 5 python sockets network-programming python-sockets
我刚刚开始学习python网络编程。我正在阅读 Python 网络编程基础,但无法理解 s.shutdown(socket.SHUT_WR) 的使用,其中 s 是套接字对象。这是使用它的代码(其中 sys.argv[2] 是用户想要发送的字节数,四舍五入为 16 的倍数):
import socket, sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '127.0.0.1'
PORT = 1060
if sys.argv[1:] == ['server']:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
while True:
print 'Listening at', s.getsockname()
sc, sockname = s.accept()
print 'Processing up to 1024 bytes at a time from', sockname
n = 0
while True:
message = sc.recv(1024)
if not message:
break
sc.sendall(message.upper()) # send it back uppercase
n += len(message)
print '\r%d bytes processed so far' % (n,),
sys.stdout.flush()
print
sc.close()
print 'Completed processing'
elif len(sys.argv) == 3 and sys.argv[1] == 'client' and sys.argv[2].isdigit():
bytes = (int(sys.argv[2]) + 15) // 16 * 16 # round up to // 16
message = 'capitalize this!' # 16-byte message to repeat over and over
print 'Sending', bytes, 'bytes of data, in chunks of 16 bytes'
s.connect((HOST, PORT))
sent = 0
while sent < bytes:
s.sendall(message)
sent += len(message)
print '\r%d bytes sent' % (sent,),
sys.stdout.flush()
print
s.shutdown(socket.SHUT_WR)
print 'Receiving all the data the server sends back'
received = 0
while True:
data = s.recv(42)
if not received:
print 'The first data received says', repr(data)
received += len(data)
if not data:
break
print '\r%d bytes received' % (received,),
s.close()
else:
print >>sys.stderr, 'usage: tcp_deadlock.py server | client <bytes>'
Run Code Online (Sandbox Code Playgroud)
这是作者提供的解释,我发现很难理解:
其次,您将看到客户端在完成发送传输后对套接字进行了 shutdown() 调用。这解决了一个重要问题:如果服务器将永远读取直到看到文件结束,那么客户端将如何避免必须在套接字上执行完整的 close() 从而禁止自己执行许多 recv( ) 仍然需要进行调用才能接收服务器的响应?解决方案是“半关闭”套接字——即永久关闭一个方向的通信但不破坏套接字本身——这样服务器就不能再读取任何数据,但仍然可以将任何剩余的回复发送回另一个方向,仍然是开放的。
我对它将做什么的理解是它将阻止客户端应用程序进一步发送数据,从而也将阻止服务器端进一步尝试读取任何数据。
我不明白的是为什么在这个程序中使用它,我应该在什么情况下考虑在我的程序中使用它?
\n\n\n我对其作用的理解是,它将阻止客户端应用程序进一步发送数据,从而也将阻止服务器端进一步尝试读取任何数据。
\n
你的理解是正确的。
\n\n\n\n\n我不明白的是为什么在这个程序中使用它 \xe2\x80\xa6
\n
正如您自己的声明所暗示的那样,如果没有客户端,s.shutdown(socket.SHUT_WR)服务器将不会退出等待数据,而是永远坚持下去sc.recv(1024),因为不会向服务器发送连接终止请求。
\n由于服务器永远不会到达它的sc.close(),客户端也不会放弃等待数据,而是永远坚持下去s.recv(42),因为服务器不会发送连接终止请求。
\n阅读“关闭与关闭套接字?”的答案 也可能具有启发性。