ホームページ >バックエンド開発 >Python チュートリアル >Python ネットワーク プログラミング手順 1/2 ページ

Python ネットワーク プログラミング手順 1/2 ページ

WBOY
WBOYオリジナル
2016-06-16 08:47:221157ブラウズ

1. ネットワーク知識の紹介

ソケットはネットワーク接続のエンドポイントです。たとえば、Web ブラウザが www.jb51.net のホームページをリクエストすると、Web ブラウザはソケットを作成し、www.jb51.net の Web サーバー ホストに接続するように指示します。Web サーバーは、サーバーからのリクエストにも応答します。ソケット上のモニター。両端は独自のソケットを使用して情報を送受信します。

使用すると、各ソケットは特定の IP アドレスとポートにバインドされます。 IP アドレスは 4 つの数字のシーケンスであり、これら 4 つの数字はすべて 0 ~ 255 の範囲の値です (たとえば、220、176、36、76)。ポート値の範囲は 0 ~ 65535 です。 1024 未満のポート番号は、既知のネットワーク サービス (Web サービスで使用されるポート 80 など) 用に予約されており、最大予約番号はソケット モジュールの IPPORT_RESERVED 変数に格納されます。プログラムに異なるポート値を使用することもできます。

すべての IP アドレスが世界の他の地域に公開されるわけではありません。実際、一部は公開されていないアドレス (192.168.y.z や 10.x.y.z など) 用に特別に予約されています。アドレス 127.0.0.1 はローカル アドレスであり、常に現在のコンピュータを指します。プログラムはこのアドレスを使用して、同じコンピュータ上で実行されている他のプログラムに接続できます。

IP アドレスは覚えにくいため、特定の IP アドレスのホスト名またはドメイン名を登録することもできます (たとえば、222.76.216.16 の代わりに www.jb51.net を使用します)。ドメイン ネーム サーバー (DNS) は、名前と IP アドレスのマッピングを処理します。すべてのコンピュータは、正式に登録されていない場合でも、ホスト名を持つことができます。

ネットワーク経由で送信される情報の量は多くの要因に基づいて決まりますが、そのうちの 1 つは使用されるプロトコルです。多くのプロトコルは、単純な低レベルのプロトコルに基づいてプロトコル スタックを形成しています。たとえば、HTTP プロトコルは、Web ブラウザと Web サーバー間の通信に使用されるプロトコルであり、TCP プロトコルに基づいており、TCP プロトコルは IP プロトコルに基づいています。

独自の 2 つのプログラム間で情報を転送する場合、通常は TCP または UDP プロトコルを選択します。 TCP プロトコルは両端間に継続的な接続を確立し、送信した情報は宛先に順番に届くことが保証されます。 UDP は接続を確立しません。高速ですが信頼性が低くなります。送信したメッセージが相手に届かないか、順番通りに届かない可能性があります。場合によっては、メッセージを一度送信しただけであっても、メッセージの複数のコピーが受信側に到着することがあります。

2. アドレスとホスト名の使用

ソケット モジュールは、ホスト名とアドレスを操作するためのいくつかの関数を提供します。

gethostname() は、プログラムが実行されているコンピューターのホスト名を返します。

>>>
'lenovo'

gethostbyname(name) 指定されたホスト名を IP アドレスとして解釈しようとします。まず、現在のコンピュータがそれを解釈できるかどうかがチェックされます。そうでない場合は、説明要求がリモート DNS サーバーに送信されます (リモート DNS サーバーは、要求が処理できるまで説明要求を別の DNS サーバーに転送することもあります)。 gethostbyname 関数は、この IP アドレスを返すか、検索が失敗した場合は例外を生成します。

>>> ソケット.gethostbyname('lenovo')
'192.168.1.4'
>>> ソケット.gethostbyname('www.jb51.net')
'222.76.216.16'

拡張形式は gethostbyname_ex(name) で、指定されたアドレスのプライマリ ホスト名と同じ IP アドレスのホスト名のリストの 3 つの要素を含むタプルを返します。選択したホスト名のリスト、および同じホスト上の同じインターフェイスの他の IP アドレスのリスト (両方のリストが空の場合もあります)。

>gt;>gt;>socket.gethostbyname('www.163.com')
'60.191.81.49'
>>>>socket.gethostbyname_ex('www.163.com') com')
('www.cache.split.netease.com', ['www.163.com'], ['60.191.81.48', '60.191.81.49
, '60.191.81.50', '60.191.81.51'、'60.191.81.52'、'60.191.81.53'、'60.191.81.54
、'220.181.28.50'、'220.181.28.51'、'220.181.28.52'、 20.181.2 8.53' , '220.181.
8.54', '220.181.31.182', '220.181.31.183', '220.181.31.184'])

gethostbyaddr(address) 関数は、gethostbyname_ex と同じ効果があります。パラメータは IP アドレス文字列です:

>>>socket.gethostbyaddr('202.165.102.205')
('homepage.vip.cnb.yahoo.com' 、['www .yahoo.com.cn']、['202.165.102.205'])

getservbyname(service,protocol) 関数にはサービス名 ('telnet' や 'ftp' など) が必要です。プロトコル (' tcp' や 'udp' など) は、サービスで使用されるポート番号を返します:

>>>socket.getservbyname('http','tcp')
80
>> ;>socket.getservbyname('telnet','tcp)
23

通常、Python 以外のプログラムは、32 ビット バイトのパケットに IP アドレスを格納して使用します。 inet_aton(ip_addr) 関数と inet_ntoa(packed) 関数は、次の形式と IP アドレスの間で変換を行います:

>>> > >>>socket.inet_ntoa('xdeLxd8x10')
'222.76.216.16'

socket は、予約された IP アドレスを表すいくつかの変数も定義します。INADDR_ANY と INADDR_BROADCAST は、それぞれ任意の IP アドレスとブロードキャスト アドレスを表す予約済みの IP アドレスです。INADDR_LOOPBACK は、常にアドレス 127.0.0.1 を持つループバック デバイスを表します。これらの変数は 32 ビットのバイト数の形式です。

getfqdn([name]) 関数は、指定されたホスト名の完全修飾ドメイン名を返します (省略した場合は、ローカル マシンの完全修飾ドメイン名が返されます)。

3. 低レベルのソケット通信を使用する

Python にはソケットの使用を容易にするいくつかのパッケージが用意されていますが、ソケットを直接使用して動作させることもできます。

1. ソケットの作成と破棄

ソケット モジュールのsocket(family,type[,proto])関数は、新しいソケット オブジェクトを作成します。通常、family の値は AF_INET です。 type の値は通常、SOCK_STREAM (直接接続、信頼性の高い TCP 接続の場合) または SOCK_DGRAM (UDP の場合) です。 socket(AF_INET,SOCK_STREAM)

family パラメーターと type パラメーターはプロトコルを暗黙的に示しますが、socket の 3 番目のオプションのパラメーター (IPPROTO_TCP や IPPROTO_RAW などのプロトコル値) を使用して、使用するプロトコルを指定できます。 IPPROTO_XX 変数を使用する代わりに、次の関数 getprotobyname を使用できます。 🎜>
fromfd(fd,type[,proto]) はめったに使用されない関数で、開いているファイル記述子からソケット オブジェクトを作成するために使用されます (ファイル記述子はファイルの fileno() メソッドによって返されます)。ファイル記述子は、ファイルではなく実際のソケットに接続されます。ソケット オブジェクトの fileno() メソッドは、このソケットのファイル記述子を返します。

完了ソケット オブジェクトを使用する場合は、close() メソッドを呼び出してソケットを明示的に閉じ、できるだけ早くリソースを解放する必要があります (ただし、ソケットはガベージ コレクターによってリサイクルされるときに自動的に閉じられます)。 )。あるいは、shutdown(how) メソッドを使用して、接続の片側または両側を閉じることもできます。パラメータ 0 はソケットによるデータの受信を禁止し、1 は送信を禁止し、2 は送受信を禁止します。

2. ソケットの接続

2 つのソケットが接続されると (たとえば、TCP を使用して)、一方の端が受信接続をリッスンして受信し、もう一方の端が接続を開始します。次のように、リスニング側はソケットを作成し、bind(address) 関数を呼び出して特定のアドレスとポートをバインドし、listen(backlog) を呼び出して着信接続をリッスンし、最後に accept() を呼び出して新しい着信接続を受信します。はサーバー側のコードです:

>>> s=socket(AF_INET,SOCK_STREAM)
>>> )
>>> s.listen(1)
>>> q,v=s.accept() #ソケット q とアドレス v を返します

上記のコードは、接続が確立されるまで待機します。次に、クライアントとして使用する別の Python インタープリターを開き、次のコードを入力します。
>>> s=socket(AF_INET,SOCK_STREAM) >>>> s.connect(('127.0.0.1',44444) #接続の開始

それでは、接続が確立されているかどうかを確認してみましょう。サーバー側で次のコードを入力します。メッセージ:

>>> q.send('hello,i from pythontik.com') 注: send() の引数 1 は str ではなく、string またはbuffer でなければならない場合があります。エラーが発生する場合があります。理由としては、マシンが UTF-8 文字セットをサポートしていないことが考えられます。一時的な解決策は q.send(b' hello...')
31 #送信されたバイト数

です。クライアント 次のコードを入力してメッセージを受信します:
>>> s.recv(1024)
'こんにちは、pythontik.com から来ました'

渡すアドレスbinding と connect は、AF_INET ソケットのタプル (ipAddress,port) です。connect の代わりに、connect_ex(address) メソッドを呼び出すこともできます。C の connect への基本的な呼び出しがエラーを返した場合、connect_ex もエラーを返します。それ以外の場合は、例外を発生させるのではなく、成功を表す 0) を返します。

listen を呼び出すときは、待機キューに入れることができる受信接続の合計数を表すパラメータを指定します。待機キューがいっぱいになると、リモート エンドに接続が拒否されたことが通知されます。ソケット モジュールの SOMAXCONN 変数は、待機キューが収容できる最大数を示します。変数 v の値は次のとおりです。
('127.0.0.1', 1334) )

UDP は非直接接続ですが、指定された宛先アドレスとポートを使用して connect を呼び出し、

3. データを送受信します。 >関数 send(string[ ,flags]) は、指定された文字列をリモートソケットに送信します。 sendto(string[,flags],address) は、指定された文字列を特定のアドレスに送信します。通常、send メソッドは信頼性の高い接続を持つソケットに使用され、sendto メソッドは信頼性の低い接続を持つソケットに使用されますが、UDP ソケットで connect を呼び出して特定のターゲットとの接続を確立する場合は、send メソッドを使用して次のことを行うこともできます。 sendto を置き換えます。

send と sendto は両方とも、実際に送信されたバイト数を返します。大量のデータを素早く送信する場合、すべての情報が送信されたことを確認したい場合は、次のような関数を使用できます:

defsafeSend(sock,msg):
send=0
while msg:
i=sock.send(msg)
if i==-1: #エラーが発生しました
return -1
sent+=i
msg =msg[ i:]
time.sleep(25)
return send

recv(bufsize[,flags]) メソッドは受信メッセージを受信します。大量のデータが待機している場合は、以前の bufsize バイト数のデータのみを返します。 recvfrom(bufsize[,flags]) は、AF_INET ソケットを使用し、戻り値が (data,(ipAddress,port)) であることを除いて、同じことを行います。これにより、メッセージの送信元を知ることができます (これは、メッセージ以外の場合に役立ちます) -接続されたソケット) 。

send、sendto、recv、recvfrom メソッドにはすべてオプションのパラメーター フラグがあり、デフォルト値は 0 です。フラグの値は、socket.MSG_* 変数を (ビットごとの OR) 組み合わせることによって確立できます。これらの値はプラットフォームによって異なりますが、最も一般的な値は次のとおりです:

MSG_OOB: 帯域外データ (つまり、TCP 緊急データ) を処理します。
MSG_DONTROUTE: インターフェイスに直接送信されるルーティング テーブルは使用されません。
MSG_PEEK: 待機中のデータをキューから削除せずに返します。

たとえば、受信を待っているメッセージがある開いているソケットがある場合、受信データ キューからメッセージを削除せずにメッセージを受信できます。

> ;>> q.recv(1024,MSG_PEEK)
'hello'
>>> q.recv(1024,MSG_PEEK) #削除されていないので再取得可能です。
'hello'

makefile([mode[,bufsize]]) メソッドは、ソケットをカプセル化するファイル クラス オブジェクトを返します。これにより、後でファイル パラメーターを必要とするコードに渡すことができます (おそらく、 send と recv の代わりに file メソッドを使用することを好みます)。オプションの mode パラメーターと bufsize パラメーターは、組み込みの open 関数と同じ値を持ちます。

4. ソケット オプションを使用します。

ソケット オブジェクトの getpeername() メソッドと getsockname() メソッドは両方とも、IP アドレスとポートを含むタプルを返します (このタプルの形式はあなたのものと似ています)接続とバインドに渡されます)。 getpeername は接続されたリモート ソケットのアドレスとポートを返し、getsockname はローカル ソケットに関する同じ情報を返します。

デフォルトでは、ソケットはブロックされています。これは、タスクが完了するまでソケット メソッド呼び出しが返されないことを意味します。たとえば、送信データを保存しているキャッシュがいっぱいで、さらにデータを送信しようとすると、さらにデータをキャッシュに入れることができるまで、send の呼び出しはブロックされます。 setblocking(flag) メソッド (フラグ値は 0、setblocking(0)) を呼び出してソケットを非ブロックにすることで、このデフォルトの動作を変更できます。ソケットが非ブロッキングの場合、実行されたアクションがブロッキングを引き起こす場合、エラー例外が発生します。次のコードは、継続的に新しい接続を受け入れ、関数 processRequest を使用してそれらを処理しようとします。新しい接続が無効な場合は、0.5 秒後に再試行されます。もう 1 つの方法は、リスニング ソケットで select または Paul を呼び出して、新しい接続の到着を検出することです。

他のソケット オプションは、setsockopt(level,name,value) メソッドと getsockopt(level,name[,buflen]) メソッドを使用して設定および取得できます。ソケットはプロトコル スタックのさまざまな層を表し、level パラメーターはオプションがどの層に適用されるかを指定します。 level の値は SOL_ で始まります (SOL_SOCKET、SOL_TCP など)。名前は、どのオプションを扱っているかを示します。 value については、オプションに数値が必要な場合、value には数値のみを渡すことができます。バッファ (文字列) を渡すこともできますが、正しい形式を使用する必要があります。 getsockopt の場合、buflen パラメーターを指定しないことは、数値を要求してその値を返すことを意味します。 buflen を指定すると、getsockopt は、最大長が buflen のバイト数であるバッファを表す文字列を返します。次の例では、送信用のソケットのバッファ サイズを 64KB に設定します。

>>> SO_SNDBUF,65535)

ルーターによってドロップされるまでのパケットの有効期間 (TTL) とホップ数を取得するには、次のコードを使用できます。 ; s.getsockopt(SOL_IP,IP_TTL)
32

5. 数値変換

プラットフォームごとにバイト順序が異なるため、標準のネットワーク バイト順序を使用します。 nthol(x) 関数と ntohs(x) 関数はネットワーク バイト オーダーの値を受け取り、それを現在のホスト バイト オーダーの同じ値に変換しますが、htonl(x) と htons(x) はその逆を行います:

>>> import.socket
>>>socket.htons(20000) #16 ビット値に変換
>>> ( 20000) #32 ビット値に変換
541982720
>>>socket.ntohl(541982720)
20000

SocketServers を使用

SocketServers モジュールソケット サービス クラスのセットは、着信ソケット接続のリッスン、受け入れ、処理の詳細を凝縮して非表示にする基本クラスを定義します。

1. SocketServers ファミリ
TCPServer と UDPServer はどちらも SocketServer のサブクラスであり、それぞれ TCP 情報と UDP 情報を処理します。
注: SocketServer は、UnixStreamServer (TCPServer のサブクラス) および UNIXdatagramServer (UDPServer のサブクラス) も提供します。これらは、待機ソケットの作成時に AF_INET の代わりに AF_UNIX が使用される点を除いて、親クラスと同じです。

デフォルトでは、ソケット サービスは一度に 1 つの接続を処理しますが、ThreadingMixIN クラスと ForkingMixIn クラスを使用して、任意の SocketServer のスレッドとサブプロセスを作成できます。実際、SocketServer モジュールには、問題を解決するためのいくつかの便利なクラスが用意されています。ForkingUDPServer、ForkingTCPServer、ThreadingUDPServer、ThreadingTCPServer、ThreadingUnixStreamServer、ThreadingUnixDatagramServer です。

SocketServer は、受信接続を通常の方法で処理します。これをより便利にするには、処理するソケットを渡すことができるように、独自のリクエスト ハンドラー クラスをそれに提供する必要があります。 SocketServer モジュールの BaseRequestHandler クラスは、すべてのリクエスト ハンドラーの親クラスです。たとえば、マルチスレッドの電子メール サーバーを作成する必要があるとします。まず、BaseRequestHandler のサブクラスである MailRequestHandler を作成し、それを新しく作成した SocketServer に渡します:
import SocketServer
.. #MailRequestHandler を作成します
addr=('220.172.20.6',25) #リスニング アドレスとポート
server=SocketServer.ThreadingTCPServer(addr,M​​ailRequestHandler)
server.serve_forever()

新しい接続が到着するたびに、サーバーは新しい MailRequestHandler インスタンスを作成し、その handle() メソッドを呼び出して新しいリクエストを処理します。サーバーは ThreadingTCPServer を継承しているため、新しいリクエストごとに別のスレッドを開始してリクエストを処理し、複数のリクエストを同時に処理できるようにします。 server_forever の代わりに handle_request() を使用すると、接続リクエストが 1 つずつ処理されます。 server_forever は handle_request を繰り返し呼び出すだけです。

通常、ソケット サービスの 1 つを使用するだけですが、独自のサブクラスを作成する必要がある場合は、以下で説明するメソッドをオーバーライドしてカスタマイズできます。

サービスが最初に作成されるとき、__init__ 関数は、server_bind() メソッドを呼び出して、リッスンしているソケット (self.socket) を正しいアドレス (self.server_address) にバインドします。次に、server_activate() を呼び出してサービスをアクティブ化します (デフォルトでは、ソケットの listen メソッドが呼び出されます)。

このソケット サービスは、handle_request メソッドまたはserve_forever メソッドが呼び出されるまで何も行いません。 handle_request は get_request() を呼び出して新しいソケット接続を待機して受信し、次に verify_request(request, client_address) を呼び出してサービスが接続を処理するかどうかを確認します (これはアクセス制御で使用でき、verify_request はデフォルトで常に true を返します)。リクエストが処理される場合、handle_request は process_request(request, client_address) を呼び出します。 process_request(request, client_address) によって例外が発生した場合は、handle_error(request, client_address) が呼び出されます。デフォルトでは、process_request は単にfinish_request(request, client_address) を呼び出します。子プロセスとスレッド クラスはこの動作をオーバーライドして、新しいプロセスまたはスレッドを開始してから、finish_request を呼び出します。 finish_request は新しいリクエスト ハンドラーをインスタンス化し、リクエスト ハンドラーは順番に handle() メソッドを呼び出します。

SocketServer は新しいリクエスト ハンドラーを作成するときに、ハンドラーがサービスに関する情報にアクセスできるように、ハンドラーの __init__ 関数の self 変数を渡します。

SocketServer の fileno() メソッドは、リッスンしているソケットのファイル記述子を返します。 address_family メンバー変数は、リッスンするソケットのソケット ファミリ (AF_INET など) を指定し、server_address には、リッスンするソケットがバインドされるアドレスが含まれます。ソケット変数には、待機中のソケット自体が含まれます。

2. リクエスト ハンドラー

リクエスト ハンドラーには setup()、handle()、およびfinish() メソッドがあり、これらをオーバーライドして独自の動作をカスタマイズできます。通常は、ハンドル メソッドをオーバーライドするだけで済みます。 BaseRequestHandler の __init__ 関数は setup() メソッドを呼び出して初期化作業を実行し、handle() はリクエストを処理し、finish() はクリーンアップ作業を実行するために使用されます。handle または setup によって例外が発生した場合、finish は呼び出されません。リクエスト ハンドラーはリクエストごとに新しいインスタンスを作成することに注意してください。

request メンバー変数は、ストリーミング (TCP) サービス用に最後に受け入れられたソケットを保持します。データグラム サービスの場合は、受信メッセージとリッスン ソケットを含むタプルです。 client_address には送信者のアドレスが含まれ、server には SocketServer への参照があります (これを通じて、server_address などのメンバーにアクセスできます)。

次の例では、サーバーとして機能し、クライアントから送信されたデータをクライアントに送り返す EchoRequestHandler を実装しています。 >> class EchoRequestHandler(SocketServer.BaseRequestHandler):
... def handle(self):
... print '新しい接続を取得しました!'
... while 1:
。 .. mesg=self.request.recv(1024)
... そうでない場合、msg:
... ブレーク
... print 'Received:',msg
... self。 request.send(msg)
... print '接続完了'
>>>>server=SocketServer.ThreadingTCPServer(('127.0.0.1',12321),EchoReuestHandler)
> >> server.handle_request() #実行後、接続を待ちます
受信しました: こんにちは!
受信しました:
接続が完了しました!
別の Python インタープリターをクライアントとして開き、次のコードを実行します。 )
>>> s.connect(('120.0.0.1',12321))
>>> s.send('Hello!')
6
> ; >> print s.recv(1024)
こんにちは
>>>
16
>>> print s.recv(1024)
火曜日が好きです!
>>> s.close()

SocketServer モジュールは、BaseRequestHandler と DatagramRequestHandler の 2 つのサブクラスも定義します。これらは、setup メソッドとfinish メソッドをオーバーライドし、2 つのファイル オブジェクト rfile と wfile を作成します。これらを使用して、ソケット メソッドを使用する代わりにクライアントとの間でデータの読み書きを行うことができます。

ソケットのブロッキングまたは同期プログラミング


1. ソケットの使用

ネットワーク プログラミングの最も基本的な部分はソケット (ソケット) です。ソケットには、サーバー ソケットとクライアント ソケットの 2 種類があります。サーバーソケットを作成した後、接続を待つように指示します。その後、クライアントが接続するまでネットワーク アドレス (xxx.xxx.xxx.xxx:xxx など) をリッスンします。その後、両端が通信できるようになります。

クライアント ソケットの処理は、通常、サーバー ソケットの処理よりも少し簡単です。サーバーは常にクライアントからの接続を処理できるように準備しておく必要があり、複数の接続を処理する必要がありますが、クライアントは単純な接続のみを必要とするためです。何かをして接続を切断します。

ソケットをインスタンス化するとき、次の 3 つのパラメータを指定できます: アドレス シリーズ (デフォルトはソケット.AF_INET)、ストリーム ソケット (デフォルト値はソケット.SOCK_STREAM) またはデータグラム ソケット (socket.SOCK_DGRAM)、プロトコル(デフォルトは 0)。単純なソケットの場合、パラメータを指定せず、すべてのデフォルト値を使用できます。

サーバーソケットは、bind メソッドを使用して指定されたアドレスをリッスンした後、listen メソッドを呼び出します。次に、クライアント ソケットは、connect メソッドを使用してサーバーに接続できます (connect メソッドで使用されるアドレス パラメーターは、bind と同じです)。 listen メソッドにはパラメーターが必要です。これは、待機中の接続キューに含めることができる接続の数です。

サーバーソケットは listen メソッドを呼び出すと、listen 状態に入り、通常は無限ループを使用します。 1. ゲストルームからの接続の受け入れを開始します。これは、accept メソッドを呼び出すことによって実現されます。このメソッドを呼び出した後は、クライアントが接続するまでブロック状態になります (クライアントが接続を開始するのを待機します)。接続後、accept は (クライアント, アドレス) の形式でタプルを返します。クライアントは値です。クライアントとの通信に使用されるソケット、アドレスは xxx.xxx.xxx.xxx:xxx の形式のクライアントのアドレスです。 2. 次に、サーバーはクライアントの要求を処理します。 3. 処理が完了すると、1 が呼び出されます。

データの送信に関して、socketにはsendとrecvの2つのメソッドがあります。 send は文字列パラメータを使用してデータを送信します。recv パラメータは一度に受信するデータの量を示すバイト数です。一度に受信するデータの量がわからない場合は、1024 を使用するのが最適です。 。

以下は最小限のサーバー/クライアントの例です:

サーバー:

インポートソケット
s =ソケット.socket()
ホスト =ソケット.gethostname ()
port = 1234
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept ()
print '接続元', addr
c.send('接続してくれてありがとう')
c.close()

クライアント:

インポートソケット
s = ソケット.ソケット()
ホスト =ソケット.gethostname()
ポート = 1234
s.connect((ホスト, ポート))
print s.recv(1024 )

注: Ctrl-C を使用してサーバーを停止した場合、同じポートを再度使用する場合は、しばらく待つ必要がある場合があります。

2. SocketServer を使用する

SocketServer モジュールは、ネットワーク サーバーの作成作業を簡素化します。
これは、TCPServer (TCP プロトコルを使用)、UDPServer (データグラムを使用)、UnixStreamServer、

UnixDatagramServer の 4 つの基本サービス クラスを提供します。 UnixStreamServer と UnixDatagramServer は、Unix 類似のプラットフォームで使用されます。
これら 4 つのクラスはすべて、同期メソッドを使用してリクエストを処理します。つまり、現在のリクエスト処理は、次のリクエスト処理が開始される前に

完了する必要があります。

SocketServer を使用してサーバーを作成するには、次の 4 つの手順が必要です。

1. BaseRequestHandler クラスをサブクラス化し、受信した

リクエストを処理するためにその handle() メソッドをオーバーライドすることにより、リクエスト プロセッサ クラスを作成します。 ;
2. TCPServer などのサービス クラスをインスタンス化し、それにパラメーターを渡します: サーバー アドレスとリクエスト ハンドラー クラス;
3. サービス インスタンス オブジェクトの handle_request() またはserve_forever() メソッドを呼び出してリクエストを処理します。

以下では、SocketServer を使用して、同期メソッドを使用する最も単純なサーバーを作成します。

from SocketServer import TCPServer, StreamRequestHandler
#最初のステップ。 StreamRequestHandler クラスは、BaseRequestHandler クラスのサブクラスであり、ストリーム ソケットの
#rfile メソッドと wfile メソッドを定義します。
class Handler(StreamRequestHandler):
addr = self.request .getpeername()
print '接続を取得しました', addr
self.wfile.write('接続してくれてありがとう')

#2 番目のステップ。ここで、'' はサーバーを実行しているホストを表します。
server = TCPServer(('', 1234), Handler)
#ステップ 3. serve_forever() の結果、ループ状態になります。
server.serve_forever()

注: ブロッキングまたは同期メソッドを使用して接続できるクライアントは一度に 1 つだけであり、次のクライアントは処理後にのみ接続できます。完成しました。

ノンブロッキングまたは非同期プログラミング

現在の 1/2 ページ

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