スティックのパッケージの問題
TCPプロトコルは、送信の問題の際にデータのスティッキーパケットになります
TCPとUDPの違いについての講演、データ転送プロトコル言っても良いか悪いかではないが、より良い選択プロトコルかもしれ異なるアプリケーション要件
TCP:大量に送信するのに適した、必要性が粘着性の袋があるでしょう、接続を確立するため、ステッカーパックは、入ってくるの長さを決定し、問題を解決するため、同じ長さの完全なワンタイム転送を保証することができます受け取ることができます
UDP:データ伝送の少量、ノースティックパッケージ、接続なし、1時間伝送、次は新しいデータであるに適した、欠点は不安、そのデータの損失であります
QQはUDPプロトコルを使用することができるはずです理論的には?それを使用するためにどのようなプロトコルであるが、実際の使用履歴から残された課題であるTCPプロトコルは、まだ我々は制限のQQ-時間入力を入力してくださいどのような言葉を覚えてすることができますか?それは、送信側と受信側の要求することですデータの長さは同じです。
スティックパッケージの形成のための理由
1つのデータは、時間の短い間隔次いで、非常に小さく、
2.データが大きすぎる、テイクを完了できませんでした、私たちは、次の大きなデータを取得します
問題を解決するために、パッケージをスティック
==データ転送、データ転送サイズの前に、データのサイズが固定された長さを有していなければならない==
# TCP 解决粘包问题 附带处理了一下
import socket
import struct
import subprocess
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8000))
server.listen(5)
print('start...')
# 连接循环
while True:
conn, client_address = server.accept()
print(client_address)
# 通信循环
while True:
try:
cmd = conn.recv(1024)
print(cmd)
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read()
count_len = len(stdout) + len(stderr)
guding_bytes = struct.pack('i', count_len)
conn.send(guding_bytes) # 4
conn.send(stderr + stdout)
except ConnectionResetError: # 连接循环时出现的中断
break
conn.close()
# 客户端
mport struct
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
# cmd = input('please enter your cmd you want:')
cmd = 'dir'
client.send(cmd.encode('utf8'))
guding_bytes = client.recv(4)
count_len = struct.unpack('i', guding_bytes)[0]
data = client.recv(count_len)
print(data.decode('gbk'))
UDPソケットのソケットプログラミングに基づいて、
コネクションレスUDP
# UDP服务端 import socket server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server.bind(('127.0.0.1', 8000)) print('start...') while True: data, client_addr = server.recvfrom(1024) print(client_addr) print(data) server.sendto(data.upper(), client_addr)
# UDP客户端 import socket client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: msg = input('please enter your msg:') client.sendto(msg.encode('utf8'), ('127.0.0.1', 8000)) data = client.recvfrom(1024) print(data)
そして、TCPはほぼ同じ、関数を呼び出すことは同じですが、コネクションレスUDP、TCPおよびUDPのsendto送信のため、UDP上のアドレスを直接参照することがあるのSendTo具体的な表現方法名は、同じではありません
ソケットのソケットプログラミングに基づくsocketserver並行処理を実現
5つの電話我々が書く前に警察署があり、サーバと複数のクライアントが同時に接続してみましょう一人だけ、今書かれた5つの電話5人
# 同一时刻有多个人在接听 import socketserver import subprocess import struct class MyHandler(socketserver.BaseRequestHandler): # 通信循环 def handle(self): while True: try: cmd = self.request.recv(1024) print(cmd) pipeline = subprocess.Popen(cmd.decode('utf8'), shell = True, stderr = subprocess.PIPE, stdout = subprocess.PIPE) stdout = pipeline.stdout.read() stderr = pipeline.stderr.read() count_len = len(stderr) + len(stdout) guding_bytes = struct.pack('i', count_len) self.request.send(guding_bytes) # 4 self.request.send(stderr + stdout) except ConnectionResetError: break # 使用socketserver的连接循环(并发),但是使用了自己的通信循环 # myhandler = MyHandler() if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1', 8000), MyHandler, bind_and_activate=True) print('start...') server.serve_forever()