Python学習のネットワークプログラミング

4696 ワード

Python学習ディレクトリ
  • MacでPython 3
  • を使用
  • Python学習のデータ型
  • Python学習の関数
  • Python学習の高度な特性
  • Python学習の関数式プログラミング
  • Python学習のモジュール
  • Python学習のオブジェクト向けプログラミング
  • Python学習のオブジェクト向け高度プログラミング
  • Python学習のエラーデバッグとテスト
  • Python学習のIOプログラミング
  • Python学習のプロセスとスレッド
  • Python学習の正則
  • Python学習の常用モジュール
  • Python学習のネットワークプログラミング
  • インターネットの実現は、いくつかの層に分かれている.各階には独自の機能があり、建物のように各階が次の階でサポートされています.どのように階層化するかは異なるモデルがあり、あるモデルは7層に分かれ、あるモデルは4層に分かれている.インターネットを5つの層に分けて、説明しやすいと思います.一番下の層を「ソリッド層」(Physical Layer)といい、一番上の層を「アプリケーション層」(Application Layer)といい、真ん中の3層(下から上へ)はそれぞれ「リンク層」(Link Layer)、「ネットワーク層」(Network Layer)、「トランスポート層」(Transport Layer)である.下の層ほどハードウェアに近い.上の層ほど、ユーザーに近づきます.

    TCPプログラミング


    Socketはネットワークプログラミングの抽象概念である.通常、Socketは「ネットワークリンクを開いた」ことを表し、Socketを開くにはターゲットコンピュータのIPアドレスとポート番号を知ってからプロトコルタイプを指定する必要があります.

    クライアント


    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オブジェクトは正常に作成されますが、接続は確立されていません.

    接続サーバ

    s.connect(('www.sina.com.cn', 80))
    

    注意パラメータは、アドレスとポート番号を含むtupleです.

    リクエストの送信

    #  :
    s.send(b'GET / HTTP/1.1\r
    Host: www.sina.com.cn\r
    Connection: close\r
    \r
    ')

    TCP接続は双方向チャネルを作成し,双方が同時に相手にデータを送ることができる.しかし、誰が先に誰を送って、どのように調整するかは、具体的な協議によって決めなければならない.例えば、HTTPプロトコルは、クライアントがサーバに要求し、サーバが受信してからクライアントにデータを送信しなければならないことを規定している.

    受信データ

    #  :
    buffer = []
    while True:
        #  1k :
        d = s.recv(1024)
        if d:
            buffer.append(d)
        else:
            break
    data = b''.join(buffer)
    

    Socketを閉じる

    #  :
    buffer = []
    while True:
        #  1k :
        d = s.recv(1024)
        if d:
            buffer.append(d)
        else:
            break
    data = b''.join(buffer)
    

    サーバ


    Socketの作成

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    

    IPv 4およびTCPプロトコルに基づくSocketを作成します.

    リスナーのアドレスとポートのバインド

    #  :
    s.bind(('127.0.0.1', 9999))
    s.listen(5)
    print('Waiting for connection...')
    
    listen()メソッドによって入力されたパラメータは、接続待ちの最大数を指定します.

    クライアント接続を受け入れる

    while True:
        #  :
        sock, addr = s.accept()
        #  TCP :
        t = threading.Thread(target=tcplink, args=(sock, addr))
        t.start()
    

    各接続は、新しいスレッド(またはプロセス)を作成して処理する必要があります.そうしないと、単一のスレッドは、接続の処理中に他のクライアントの接続を受け入れることができません.
    def tcplink(sock, addr):
        print('Accept new connection from %s:%s...' % addr)
        sock.send(b'Welcome!')
        while True:
            data = sock.recv(1024)
            time.sleep(1)
            if not data or data.decode('utf-8') == 'exit':
                break
            sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
        sock.close()
        print('Connection from %s:%s closed.' % addr)
    

    UDPプログラミング


    TCPは信頼性の高い接続を確立し、通信双方がストリーム形式でデータを送信することができる.TCPに対してUDPは無接続向けのプロトコルである.
    UDPプロトコルを使用する場合、接続を確立する必要はなく、相手のIPアドレスとポート番号を知るだけで、パケットを直接送ることができます.でも、行けるかどうかはわかりません.
    UDPでデータを転送するのは信頼できないが、TCPに比べて速度が速く、信頼性の高い到着が要求されないデータに対してはUDPプロトコルを使用できるという利点がある.
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #  :
    s.bind(('127.0.0.1', 9999))
    

    Socketが作成されると、SOCK_DGRAMはこのSocketのタイプがUDPであることを指定します.バインドポートはTCPと同じですが、listen()メソッドを呼び出す必要はありません.任意のクライアントからのデータを直接受信します.
    print('Bind UDP on 9999...')
    while True:
        #  :
        data, addr = s.recvfrom(1024)
        print('Received from %s:%s.' % addr)
        s.sendto(b'Hello, %s!' % data, addr)
    
    recvfrom()メソッドは、データとクライアントのアドレスとポートを返し、サーバがデータを受信した後、sendto()を直接呼び出すことで、データをUDPでクライアントに送信することができる.
    この例は簡単なので、マルチスレッドを省くことに注意してください.
    クライアントがUDPを使用する場合、まずUDPベースのSocketを作成し、その後、connect()を呼び出す必要がなく、sendto()を介してサーバに直接データを送信します.
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for data in [b'Michael', b'Tracy', b'Sarah']:
        #  :
        s.sendto(data, ('127.0.0.1', 9999))
        #  :
        print(s.recv(1024).decode('utf-8'))
    s.close()
    

    サーバからデータを受信してもrecv()メソッドが呼び出されます.