スティックのパッケージの問題
問題は、パッケージを貼り、その後は何ですか?
私たちは、TCPソケットプログラミングを記述する場合は、TCPプロトコルは、ストリーミングプロトコルで、初めてサーバーによって送信されたデータは、1回のクライアントを正確に受信することはできません、最後のデータで送られた次のデータが一緒に固執します。
すなわち:
1は、相手方の長さを予測することはできませんデータのサイズが受信する必要があります
図2は、送信されたデータの連続少量、及びデータの短い時間間隔の複数の使い捨てパッケージと一緒に送信されます
TCPプロトコルの機能:
データの複数の少量連続的に送信し、ワンタイムデータ送信の短い時間間隔が終了します
サブプロセスモジュール
私たちは、スティックのパッケージの問題を示すために、subprocessモジュールを使用しています。
# 服务端
# coding=utf-8
import socket
import subprocess
server = socket.socket()
address = ("127.0.0.1",8888)
server.bind(address)
server.listen(5)
while True:
conn , addr = server.accept()
while True:
try:
cmd = conn.recv(1024).decode("utf-8")
print(cmd)
if cmd == "q":
break
obj = subprocess.Popen(
cmd,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
res = obj.stdout.read() + obj.stderr.read()
conn.send(res)
except Exception:
break
conn.close()
# 客户端
# coding=utf-8
import socket
client = socket.socket()
address = ("127.0.0.1",8888)
client.connect(address)
while True:
cmd = input("请输入>>>")
client.send(cmd.encode("utf-8"))
if cmd == "q":
break
data = client.recv(1024)
print(data.decode("gbk"))
client.close()
ターミナル印刷結果
请输入>>>tasklist
映像名称 PID 会话名 会话# 内存使用
========================= ======== ================ =========== ============
System Idle Process 0 Services 0 24 K
System 4 Services 0 3,172 K
smss.exe 352 Services 0 1,200 K
csrss.exe 464 Services 0 6,656 K
wininit.exe 572 Services 0 5,168 K
csrss.exe 588 Console 1 77,948 K
services.exe 636 Services 0 12,288 K
lsass.exe 652 Services 0 11,164 K
lsm.exe 660 Services 0 4,664 K
winlogon.exe 744 Console 1 8,180 K
svchost.exe 812 Services 0 10,040 K
svchost.
请输入>>>dir
exe 892 Services 0 8,280 K
svchost.exe 980 Services 0 21,744 K
svchost.exe 168 Services 0 21,060 K
svchost.exe 388 Services 0 40,792 K
svchost.exe 908 Services 0 12,252 K
WUDFHost.exe 1100 Services 0 8,096 K
ZhuDongFangYu.exe 1188 Services 0 23,784 K
svchost.exe 1236 Services 0 17,532 K
wlanext.exe 1412 Services 0 5,268 K
conhost.exe 1420 Services 0 2,860 K
dwm.exe 1536 Console 1 38,436 K
explorer.exe 1588 Console 1 70,028 K
spoolsv.exe 1612 Services 0 12,204 K
svchost.exe
我々は敗者タスクリストコマンドの後に見て、再び他のコマンドを入力するか、前のコマンドの結果、
だから、最初の時間のための長い実績のあるデータ・サーバは、ワンタイムクライアントが正確に受信することはできません送信され、最後のデータで送られた次のデータが一緒に固執します。私たちは、1024バイトのデータサイズが受信されたクライアントで受信し、サーバーは、それが実行結果の次の権利はありませんが、実行結果は結果がバックと同等になるように、ヒープのサイズを超えて一緒に送信され、受信します、その後、我々はあなたが構造体のモジュールを使用する必要があり、この問題を解決する必要があります
構造体モジュール
構造体モジュール,,ヘッダは、最初の送信ヘッダを定義し、次に実際のデータを送信しなければなりません
# 服务端
# coding=utf-8
import struct
import socket
import subprocess
server = socket.socket()
address = ("127.0.0.1",8888)
server.bind(address)
server.listen(5)
while True:
conn,addr = server.accept()
while True:
try:
cmd = conn.recv(1024).decode("utf-8")
print(cmd)
if cmd == "q":
break
obj = subprocess.Popen(
cmd ,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
res = obj.stdout.read() + obj.stderr.read()
# 将执行结果计算长度用i模式打包
res_len = struct.pack("i",len(res))
# 先发送数据长度
conn.send(res_len)
# 再发送真实数据
conn.send(res)
except Exception:
break
conn.close()
# 客户端
# coding=utf-8
import socket
import struct
client = socket.socket()
address = ("127.0.0.1",8888)
client.connect(address)
while True:
cmd = input("请输入命令>>>")
client.send(cmd.encode("utf-8"))
if cmd == "q":
break
# 用struct模块接收的长度统一是4个字节,
head = client.recv(4)
# 然后用struct模块解包得到数据的真实长度,返回的是元组类型,0表示第一个元素,就是真实长度
data_len = struct.unpack("i",head)[0]
# 然后再把真实长度接收即可。
data = client.recv(data_len)
print(data.decode("gbk"))
client.close()
UDPプロトコルのプログラミング
伝送プロトコルは、UDPであります
1)双方向チャネルを確立する必要はありません。
2)パッケージをつきません
3)クライアントがサーバにデータを送信し、サーバーが返す受信成功を待たずに
4)簡単なデータ、データの不安を失います。
TCP:電話と同等
UDP:テキストメッセージの同等
簡単QQのチャットルーム
# 服务端
# coding=utf-8
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
address = ("127.0.0.1",8888)
server.bind(address)
while True:
msg,addr = server.recvfrom(1024)
print(msg.decode("utf-8"))
# 服务端往客户端发送消息
send_msg = input("服务端发送消息")
server.sendto(send_msg.encode("utf-8"),addr)
# 客户端
# coding=utf-8
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
address = ("127.0.0.1",8888)
while True:
send_msg = input("请输入信息")
client.sendto(send_msg.encode("utf-8"),address)
data = client.recv(1024)
print(data.decode("utf-8"))