Pythonネットワークプログラミングの学習を始めたばかりです。Foundations of Python Network Programming を読んでいましたが、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>'
そして、これは著者が提供する説明であり、私が理解するのが難しいと感じています:
2 番目に、クライアントが送信の送信を終了した後、ソケットで shutdown() 呼び出しを行うことがわかります。これにより、重要な問題が解決されます。サーバーがファイルの終わりを確認するまで永遠に読み取りを行う場合、クライアントはソケットで完全な close() を実行する必要がなくなり、多くの recv( ) サーバーの応答を受信するためにまだ行う必要がある呼び出しはありますか? 解決策は、ソケットを「半分閉じる」ことです。つまり、一方向の通信を永久にシャットダウンしますが、ソケット自体を破壊することはありません。これにより、サーバーはデータを読み取ることができなくなりますが、残りの応答を送り返すことができます。まだ開いている他の方向。
それが何をするかについての私の理解は、それがクライアントアプリケーションがそれ以上データを送信するのを防ぎ、したがってサーバー側がそれ以上データを読み取ろうとするのを防ぐことです。
私が理解できないのは、なぜこのプログラムで使用されているのか、どのような状況で自分のプログラムで使用することを検討すべきなのかということです.