まず、TCPプロトコルに基づいて
TCPソケットに基づいて、鍵は2つのサイクル、サイクルのリンク、通信サイクルであります
二つのカテゴリーに刻まれたsocketserverモジュール:(通信の問題を解決するために)サーバクラス(問題を解決するためのリンク)と要求クラス
1.1サーバ・クラス
1.2リクエストクラス
1.3継承
1.4サーバー
import socketserver
class MyHandler(socketserver.BaseRequestHandler):
def handle(self):
# 通信循环
while True:
# print(self.client_address)
# print(self.request) #self.request=conn
try:
data = self.request.recv(1024)
if len(data) == 0: break
self.request.send(data.upper())
except ConnectionResetError:
break
if __name__ == '__main__':
s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyHandler, bind_and_activate=True)
s.serve_forever() # 代表连接循环
# 循环建立连接,每建立一个连接就会启动一个线程(服务员)+调用Myhanlder类产生一个对象,调用该对象下的handle方法,专门与刚刚建立好的连接做通信循环
1.5クライアント
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 8080)) # 指定服务端ip和端口
while True:
# msg=input('>>: ').strip() #msg=''
msg = 'client33333' # msg=''
if len(msg) == 0: continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data)
phone.close()
1.6クライアント1
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 8080)) # 指定服务端ip和端口
while True:
# msg=input('>>: ').strip() #msg=''
msg = 'client11111' # msg=''
if len(msg) == 0: continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data)
phone.close()
第二に、UDPプロトコルに基づいて
2.1サーバー
import socketserver
class MyHandler(socketserver.BaseRequestHandler):
def handle(self):
# 通信循环
print(self.client_address)
print(self.request)
data = self.request[0]
print('客户消息', data)
self.request[1].sendto(data.upper(), self.client_address)
if __name__ == '__main__':
s = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyHandler)
s.serve_forever()
2.2クライアント
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udp
while True:
# msg=input('>>: ').strip() #msg=''
msg = 'client1111'
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
data, server_addr = client.recvfrom(1024)
print(data)
client.close()
2.3クライアント1
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udp
while True:
# msg=input('>>: ').strip() #msg=''
msg = 'client2222'
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
data, server_addr = client.recvfrom(1024)
print(data)
client.close()
三、socketserverソースコード解析
ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1', 8080),FtpServer)
ftpserver.serve_forever()
- 属性の順序を探す:ThreadingTCPServer-> ThreadingMixIn-> TCPServer-> BaseServer
- 得られたFTPSERVERの例として、第一TCPServerの中に見出さ__init__ ThreadingTCPServerクラスは、それによってserver_bindを運ぶ見つける、server_active
- FTPSERVER下serve_forever取得し、BaseServerは、BaseServerでも同様である実行、さらにself._handle_request_noblockを()、見つかりました
- self._handle_request_noblockを実行する()self.process_request(リクエスト、client_address)を行い、次に、((TCPServerのは))(self.socket.acceptである)client_address = self.get_request、追加要求を行います
- 同時性に対処するためのThreadingMixInのprocess一、開いた複数のスレッドで発見し、その後process_request_threadを実行し、実行self.finish_request(リクエスト、client_address)
- 4つの、部分的に完成サイクルリンク、通信処理部のこの部分は、入力BaseServerでfinish_request見つけ、トリガーはクラスの私たち自身の定義をインスタンス化し、__init__メソッドを移動して、クラスの私たち自身の定義は、このメソッドを持っていないようになりましたその親クラスに見つけるBaseRequestHandlerである....
3.1ソースの概要
- の私たち自身の定義socketserverのTCPベースのクラス
- あるself.serverソケットオブジェクト
- リンクですself.request
- self.client_addressですすなわちクライアントアドレス
- の私たち自身の定義socketserverのUDPベースのクラス
- self.requestタプルなるよう(b'adsf」として、(最初の要素は、クライアントによって送信されたデータであり、サーバは、UDPソケットオブジェクトの第二の部分である)、<socket.socket FD = 200、家族= AddressFamily.AF_INET、タイプ= SocketKind.SOCK_DGRAM、プロト= 0、LADDR =( '127.0.0.1'、8080)>)
- self.client_addressですすなわちクライアントアドレス