ホームページ  >  記事  >  バックエンド開発  >  高度な Python 学習のためのソケットの詳細な紹介

高度な Python 学習のためのソケットの詳細な紹介

高洛峰
高洛峰オリジナル
2017-03-19 14:57:521304ブラウズ

Socket の本来の英語の意味は「穴」または「ソケット」です。 BSD UNIX のプロセス通信メカニズムとして、一般に「ソケット」とも呼ばれます。これは、IP アドレスとポートを記述するために使用され、通信チェーンのハンドルであり、異なる仮想マシンまたは異なるコンピューター間の通信を実装するために使用できます。 。

ネットワーク上の 2 つのプログラムは、双方向通信接続を通じてデータを交換します。この接続の一端はソケットと呼ばれます。

ネットワーク通信接続を確立するには、少なくとも 1 組のポート番号 (ソケット) が必要です。ソケットの本質は、TCP/IPをカプセル化するプログラミングインターフェースです。これは、プログラマーがネットワーク開発に使用できるインターフェースも提供します。 car は、データのカプセル化または表示の特定の形式を提供します。Socket は、ネットワーク経由で通信する機能を提供するエンジンです。

Python

のソケットについて話しましょう。 1.socketモジュール

ソケットを作成するにはsocket.socket()

関数

を使用します。構文は次のとおりです: socket.socket(socket_family,socket_type,protocol=0)

socket_family には次のパラメータを指定できます:

socket.AF_INET IPv4 (デフォルト)

socket.AF_INET6

sock et.AF_UNIX では、単一の Unix システムのプロセス間通信にのみ使用されます

socket_type は次のパラメータになります:

socket.SOCK_STREAM ストリーミングソケット、

TCP用(デフォルト)

socket.SOCK_DGRAM データグラムソケット、UDP用

socket.SOCK_RA W オリジナルのソケットでは、通常のソケットは ICMP や IGMP などのネットワーク メッセージを処理できませんが、SOCK_RAW は特殊な IPv4 メッセージも処理できます。さらに、生のソケットを使用すると、ユーザーが次のように IP_HDRINCL ソケット オプションを渡すことができます。 IPヘッダー。

socket.SOCK_RDM は UDP の信頼できる形式であり、データグラムの配信を保証しますが、順序は保証しません。 SOCK_RAM は、元のプロトコルへの低レベルのアクセスを提供するために使用され、ICMP メッセージの送信など、特定の特殊な操作を実行する必要がある場合に使用されます。 SOCK_RAM は通常、パワー ユーザーまたは管理者によって実行されるプログラムに制限されます。

socket.SOCK_SEQPACKET 信頼性の高い連続パケットサービス

プロトコルパラメータ:

0 (デフォルト) 0の場合、システムはアドレス形式とソケットカテゴリに基づいて自動的に選択します。プロトコル

2. Socket

Object

組み込みメソッド

サーバー側ソケット関数

s.bind() アドレス(IPアドレス、ポート)をソケットにバインド、パラメータはタプルである必要があります。 s.bind(('127.0.0.1',8009))

s.listen(5) リッスンを開始します。5 は保留中の接続の最大数です

s.accept() クライアント接続を受動的に受け入れ、ブロックし、接続を待機します

クライアントソケット関数

s.connect() サーバーに接続します。パラメータはタプル形式である必要があります。例: s.connect(('127,0.0.1',8009))

Public の目的ソケット関数

s.recv(1024) は TCP データを受信するためのもので、1024 は 1 回のデータ受信のサイズです

s.send(bytes) は TCP データを送信するため、Python3 の送信データの形式はバイト形式である必要があります

s.sendall() データを完全に送信し、内部

ループを呼び出します。 send

s.close() ソケットを閉じます 例 1. ソケットプログラムの簡単な実装

サーバー側

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import time
IP_PORT = ('127.0.0.1',8009)
BUF_SIZE = 1024
 
tcp_server = socket.socket()
tcp_server.bind(IP_PORT)
tcp_server.listen(5)
 
while True:
    print("waiting for connection...")
    conn,addr = tcp_server.accept()
    print("...connected from:",addr)
    while True:
        data = tcp_server.recv(BUF_SIZE)
        if not data:break
        tcp_server.send('[%s] %s'%(time.ctime(),data))
 
tcp_server.close()

上記の説明コード:

1~4行

最初の行はUnix起動情報行で、その後にタイムモジュールとソケットモジュールがインポートされます

5~10行目

IP_PORTはグローバル

変数

宣言されたIPアドレスとポートです、bind() 関数がこのアドレスにバインドされていることを示します。上記では、バッファ サイズを 1K に設定し、listen() 関数は同時に受信できる接続の最大数を示し、それ以降の接続は拒否されます

11~到最后一行

在进入服务器的循环后,被动等待连接的到来。当有连接时,进入对话循环,等待客户端发送数据。如果消息为空,表示客户端已经退出,就跳出循环等待下一个连接到来。得到客户端消息后,在消息前面加一个时间戳然后返回。最后一行不会执行,因为循环不会退出所以服务端也不会执行close()。只是提醒不要忘记调用close()函数。

client端

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
 
HOST = '127.0.0.1'
PORT = 8009
BUF_SIZE = 1024
ADDR = (HOST,PORT)
 
client = socket.socket()
client.connect(ADDR)
 
while True:
    data = input(">>> ")
    if not data:break
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
     
client.close()

5~11行

HOST和PORT变量表示服务器的IP地址与端口号。由于演示是在同一台服务器所以IP地址都是127.0.0.1,如果运行在其他服务器上要做相应的修改。端口号要与服务器端完全相同否则无法通信。缓冲区大小还是1K。

客户端套接字在10行创建然后就去连接服务器端

13~21行

客户端也无限循环,客户端的循环在以下两个条件的任意一个发生后就退出:1.用户输入为空的情况或者服务器端响应的消息为空。否则客户端会把用户输入的字符串发送给服务器进行处理,然后接收显示服务器返回来的带有时间戳的字符串。

运行客户端程序与服务端程序

以下是客户端的输入与输出

[root@pythontab]# python client.py 
>>> hello python
[Thu Sep 15 22:29:12 2016] b'hello python'

以下是服务端输出

[root@pythontab]# python server.py 
waiting for connection...
...connected from: ('127.0.0.1', 55378)

3.socketserver模块

socketserver是标准库中的一个高级别的模块。用于简化实现网络客户端与服务器所需要的大量样板代码。模块中已经实现了一些可以使用的类。

实例1:使用socketserver实现与上面socket()实例一样的功能

服务端程序代码

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socketserver
import time
 
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
 
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            print("...connected from:",self.client_address)
            data = self.request.recv(BUF_SIZE)
            if not data:break
            self.request.send(bytes("%s %s"%(time.ctime(),data)))
 
server = socketserver.ThreadingTCPServer(ADDR,Myserver)
print("waiting for connection...")
server.serve_forever()

11~17行

主要的工作在这里。从socketserver的BaseRequestHandler类中派生出一个子类,并重写handle()函数。

在有客户端发进来的消息的时候,handle()函数就会被调用。

19~21行

代码的最后一部分用给定的IP地址和端口加上自定义处理请求的类(Myserver)。然后进入等待客户端请求与处理客户端请求的无限循环中。

客户端程序代码

import socket
HOST = '127.0.0.1'
PORT = 8009
ADDR = (HOST,PORT)
BUF_SIZE = 1024
 
client = socket.socket()
client.connect(ADDR)
 
while True:
    data = input(">>> ")
    if not data:continue
    client.send(bytes(data,encoding='utf-8'))
    recv_data = client.recv(BUF_SIZE)
    if not recv_data:break
    print(recv_data.decode())
 
client.close()

执行服务端和客户端代码  

下面是客户端输出

[root@pythontab]# python socketclient.py 
>>> hello python
Thu Sep 15 23:53:31 2016 b'hello python'
>>> hello pythontab
Thu Sep 15 23:53:49 2016 b'hello pythontab'

下面是服务端输出

[root@pythontab]# python socketserver.py 
waiting for connection...
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)
...connected from: ('127.0.0.1', 55385)

以上が高度な Python 学習のためのソケットの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。