pythonネットワークプログラミングのTCPプログラミングクライアント

2468 ワード

Socketはネットワークプログラミングの抽象概念である.通常、Socketは「ネットワークリンクを開いた」ことを表し、Socketを開くにはターゲットコンピュータのIPアドレスとポート番号を知ってからプロトコルタイプを指定する必要があります.
クライアント
ほとんどの接続は信頼できるTCP接続です.TCP接続を作成すると,アクティブに接続を開始するのをクライアントと呼び,パッシブに応答して接続するのをサーバと呼ぶ.
例えば、ブラウザで新浪にアクセスすると、自分のコンピュータがクライアントであり、ブラウザが新浪のサーバに積極的に接続します.もしすべて順調であれば、新浪のサーバーは私たちの接続を受け入れて、1つのTCP接続は創立して、後の通信はホームページの内容を送信します.
したがって、TCP接続ベースのSocketを作成します.
#   socket :
import socket

#     socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#     :
s.connect(('www.sina.com.cn', 80))

Socketの作成時、AF_INETはIPv 4プロトコルを使用することを指定し、より先進的なIPv 6を使用する場合はAF_を指定します.INET6.SOCK_STREAMは、ストリーム向けTCPプロトコルを使用することを指定します.これにより、Socketオブジェクトは正常に作成されますが、接続は確立されていません.
クライアントがアクティブにTCP接続を開始するには、サーバのIPアドレスとポート番号を知る必要があります.新浪のウェブサイトのIPアドレスはドメイン名www.sinaを使うことができますcom.cnは自動的にIPアドレスに変換しますが、どうして新浪サーバーのポート番号を知っていますか?
答えはサーバとして、どのようなサービスを提供するか、ポート番号を固定しなければならないということです.私たちはウェブページにアクセスしたいので、新浪がウェブサービスを提供するサーバーはポート番号を80ポートに固定しなければならない.80ポートはWebサービスの標準ポートだからだ.他のサービスには、SMTPサービスが25ポート、FTPサービスが21ポートなど、対応する標準ポート番号があります.ポート番号が1024未満のものはインターネット標準サービスのポートで、ポート番号が1024より大きいものは任意に使用できます.
したがって、新浪サーバに接続するコードは次のとおりです.
s.connect(('www.sina.com.cn', 80))

注意パラメータはtupleで、アドレスとポート番号が含まれています.
TCP接続を確立すると、新浪サーバに要求を送信し、トップページに戻る内容を要求することができます.
#     :
s.send(b'GET / HTTP/1.1\r
Host: www.sina.com.cn\r
Connection: close\r
\r
')

TCP接続は双方向チャネルを作成し,双方が同時に相手にデータを送ることができる.しかし、誰が先に誰を送って、どのように調整するかは、具体的な協議によって決めなければならない.例えば、HTTPプロトコルは、クライアントがサーバに要求し、サーバが受信してからクライアントにデータを送信しなければならないことを規定している.
送信されたテキストフォーマットはHTTP規格に適合しなければならない.フォーマットに問題がなければ、新浪サーバから返されたデータを受信することができる.
#     :
buffer = []
while True:
    #       1k  :
    d = s.recv(1024)
    if d:
        buffer.append(d)
    else:
        break
data = b''.join(buffer)

データ受信時にrecv(max)メソッドを呼び出し、指定したバイト数を一度に最大で受信するため、recv()が空のデータを返すまでwhileサイクルで受信を繰り返し、受信が完了したことを示し、ループを終了する.
データを受信した後、close()メソッドを呼び出してSocketを閉じると、完全なネットワーク通信が終了します.
#     :
s.close()

受信したデータにはHTTPヘッダとウェブページ自体が含まれています.私たちはHTTPヘッダとウェブページを分離し、HTTPヘッダを印刷し、ウェブページの内容をファイルに保存する必要があります.
header, html = data.split(b'\r
\r
', 1) print(header.decode('utf-8')) # : with open('sina.html', 'wb') as f: f.write(html)

ブラウザでこのsinaを開くだけですhtmlファイルは、新浪のトップページが見えます.