.socketserverを使用して、プライマリモジュール
ThreadingTCPServer
ocketserverは、標準ライブラリにおける高度なモジュールで
作成するには、サーバー側のコードとクライアントの作成を簡素化することができますsocketserver
socketserver TCPプロトコルを使用でき
、アプリケーション・シナリオ
長期TCP接続である必要があり、コールを1つだけ維持したがsocketserver同時に複数の顧客を解決することができます通話終了する
初期化コントローラを[ハンドラハンドラクラスは、ハンドラBaseRequestHandlerメソッドを継承クラス処理される各オーバー接続操作で決定]を
[コントローラクラスのクラス名があれば継承されたように、必ずしも、ハンドラその他であってもよいですBaseRequestHandlerライン]
initは():初期化制御、初期ソケット接続情報、アドレス、等を設定する処理の例
ハンドル():各コネクションをどのように処理するかを定義します。
セットアップ():典型的にはデフォルトの設定以外の接続形態として使用されるハンドル()を実行する前に
完了():ハンドルを実行()の後。
server1 輸入 socketserverの クラスでは、MYSERVER(socketserver.BaseRequestHandler): デフ(自己)を処理: #のプリント(self.request)self.request相当ソケット服务器端的でCONN self.ret = self.request.recv(1024) 印刷(self.ret。デコード("UTF-8")) ユーザー=入力("我是服务器:") self.request.send(user.encode("UTF-8")) 場合 __name__=="__main__": サーバー= socketserver.ThreadingTCPServer((" 192.168.59.1 "、8600 )、MYSERVER) #线程 server.serve_forever() #のバインドを聞く #1 CONN、ADDR =受け入れる #self.request = CONN
CLIENT1 インポート ソケット clinet=socket.socket() clinet.connect(("192.168.59.1"、8600)) 名=入力("我是客户端:") clinet.send(name.encode("UTF-8") ) RET= clinet.recv(1024).decode("UTF-8") 、印刷(RET)
# DEF ハンドル(自己): 2番目の引数がアドレス(self.client_addressです= ADDR)であり、この自己パラメータ情報の最初の2つのパラメータを含んでいること(self.request == CONN)に注意してください
Server2の インポートSocketServer クラス(SocketServer.BaseRequestHandlerの)MYSERVER: DEFハンドル(セルフ): self.data= self.request.recv(1024).strip() self.request.sendall(self.data.upper()) を印刷(セルフ.data.decode("UTF-8")) プリント(self.client_addressです[0]) # フォームのタプルを含んself.client_addressですIPアドレスポート IF __name__=="__main__": ホスト、ポート="127.0。 0.1"、9999# 設定しallow_reuse_addressは、サーバがアドレスの再利用を可能にする socketserver.TCPServer.allow_reuse_address = Trueの #は、サーバーを作成127.0.0.1:9999にサービスアドレスをバインド =サーバーSocketServer.TCPServerの((HOST、PORT)、MYSERVER) #を永遠にメイクサーバの実行、プログラムの停止を余儀なくされていない限り )(server.serve_foreverを
CLIENT2の インポートソケット HOST、PORT="127.0.0.1"、9999 データ="こんにちは" #はソケットリンク、TCPプロトコルを使用してSOCK_STREAM代表の作成 私たちの靴下AS socket.socketとを(はsocket.AF_INET、socket.SOCK_STREAM): sock.connectを( (HOST、PORT)) #のクライアントへのリンク sock.sendall(data.encode("UTF-8")) #サーバにデータを送信する 受信= sock.recv(1024).decode("UTF-8")#サーバーからデータを受信 印刷(データ) を印刷(受信)
II。分析soketserver(ソース)
https://www.cnblogs.com/Eva-J/p/5081851.html
(継承と同様である)1.soketserver
#_ * _コーディング:UTF-8は_ * _ __author__ = ' Eva_J ' クラスベース(オブジェクト): デフTestfunc(自己): プリント(' んベースTestfunc ' ) クラス息子(ベース): デフ __init__ (自己、名): 自己.nameの = 名前 self.Testfunc() デフTestfunc(自己): プリント(' やる息子Testfunc ' ) クラスBASE2(オブジェクト): デフTestfunc(自己): 印刷("BASE2はやるTestFuncを見上げている' ) クラス、息子)孫(BASE2が見上げている: パス #sonobj =息子を(' sonobj ') sonobj孫=(' しゃべりしゃべりのしゃべりのしゃべりのしゃべりすごい" ) 印刷(sonobj.name) sonobj.Testfuncを() 上記のコードを参照してください、私たちは推測し、実行した後、どのようなコンソールはそれを印刷しますか?答えを明らかにするために、それはBASE2法の内容を印刷します、理由は非常に簡単です: これらの三つのクラスが同じTestfuncの方法がありますが、しかし、一度コンピュータにする方法を見つけるために ある従うべきシーケンス:BASE2、息子、ベースを、それは最初BASE2クラスを見つけるだろうし、このクラスは、それを見つけるための方法があるだけであり、それは、それを実行するために喜びを取ります! 印刷(孫。__mro__ ) 印刷(孫。__bases__ ) 印刷(孫。__name__ ) 印刷(孫。__dict__) プリント(sonobj。__dict__ ) 印刷(" **************************************** ************************************************** *********** 8 " ) #_ * _コード:UTF-8 _ * _ __author__ = ' Eva_J ' クラスベース(オブジェクト): デフ __init__ (自己、名): self.name = 名 自己。 Testfunc() デフTestfunc(自己): プリント(' やるベースTestfunc ' ) クラス息子(ベース): デフTestFunc(セルフ): 印刷(' 息子TestFuncを行う' ) sonobj =ソン(' sonobj ' ) #このビューであれば、我々は理解していませんか?実際には、これら2つのコードは、同じ方法で、持っている親子クラス、意味は、息子にもかかわらず、基本クラスを継承することを示している #を、初期化メソッドではなく、我々は、オブジェクトのサブクラスをインスタンス化しているため、このようself.Testfunc自己がオブジェクトのサブクラスを指し、もちろん、それは最初にそれのサブクラスでメソッドを呼び出します #。最初の例では、初期化メソッドは、親クラスで実行されるが、それでもオブジェクトのサブクラスであるの本質を変更することはできませんが、だから、 #は、私たちがTestfuncメソッドを呼び出すために自己を使用するときは常に、サブクラスのために呼び出すことが第一です。私たちは、理解することができます #彼の息子にもかかわらず、彼の父の財産を相続したが、時間を費やし、または彼らの最初を過ごすために~~~
#2番目の引数がアドレスでこの自己パラメータ情報の最初の2つのパラメータを含んでいること(self.request == CONN)を注(self.client_addressです= ADDR)