緩衝區:暫時存放傳輸資料的,防止你的程式在傳送資料的時候卡主,提高**執行效率
輸入緩衝區:recv
輸出緩衝區:send
緩衝區有長度限制
mtu最大傳輸單元,網路層限制是1500b,每次傳送資料的時候最好不要超過這個數
粘包粘包現象:
1.連續傳送小的資料,間隔時間很短,有可能一次就接受歐到了這幾個連續的情節在一起的小資料,
原因:未來提高tcp傳輸效率,內部提供了乙個叫做nagel演算法,他的意思就是未來避免你連續傳送小資料.
2.當你一次接收的資料長度小於你一次傳送的資料長度,那麼一次接收完剩下的資料會在下一次接收資料的時候一起接收
原因:面向流的傳輸
粘包的根本原因:
兩端互相不知道對方傳送資料的長度
針對上面的原因有兩種解決粘包的方法
1在傳送資料前,先傳送資料的長度,name接收根據的長度來進行接收資料
服務端:
import socket客戶端:import subprocess
server = socket.socket()
ip_port = ('192.168.15.113',8001)
server.bind(ip_port)
server.listen()
conn,addr = server.accept()
while 1:
#來自客戶端的指令
print('等待接受資訊。。。')
from_client_cmd = conn.recv(1024).decode('utf-8')
print(from_client_cmd)
sub_obj = subprocess.popen(
from_client_cmd, #客戶端的指令
shell=true,
stdout=subprocess.pipe,
stderr=subprocess.pipe,
)#接受到的返回資訊是bytes型別的,並且windows系統的預設編碼為gbk
server_cmd_msg = sub_obj.stdout.read()
# server_cmd_err = sub_obj.stderr.read().decode('gbk')
cmd_msg_len = str(len(server_cmd_msg))
print('指令返回的正確資訊的長度》',cmd_msg_len)
# print('指令返回的正確資訊》',server_cmd_msg)
# print('指令返回的錯誤資訊...',server_cmd_err)
conn.send(cmd_msg_len.encode('gbk'))
from_client_ack = conn.recv(1024).decode('utf-8')
print('from_client_ack',from_client_ack)
if from_client_ack == 'ok':
conn.send(server_cmd_msg)
else:
continue
import socket2. 把要傳送的資料打成包的形式直接傳輸client = socket.socket()
server_ip_port = ('192.168.15.113',8001)
client.connect(server_ip_port)
while 1:
msg = input('請輸入要執行的指令》')
client.send(msg.encode('utf-8'))
#先接收服務端要傳送給我的資訊的長度
from_server_msglen = int(client.recv(1024).decode('gbk'))
print('..........',from_server_msglen)
#給服務端回應乙個收到了你的首席資訊官度的確認資訊
client.send('ok'.encode('utf-8'))
#拿到首席資訊官度後,將首席資訊官度作為引數給了recv,recv就按照這個長度大小來接受服務端後面要給我傳送的資料
from_server_stdout = client.recv(from_server_msglen).decode('gbk')
print('收到的正確資訊:', from_server_stdout)
# from_server_error = client.recv(1024).decode('utf-8')
# print('收到的錯誤資訊:',from_server_error)
服務端:
import socket客戶端:import subprocess
import struct
server = socket.socket()
ip_port = ('192.168.15.113',8001)
server.bind(ip_port)
server.listen()
conn,addr = server.accept()
while 1:
#來自客戶端的指令
print('等待接受資訊。。。')
from_client_cmd = conn.recv(1024).decode('utf-8')
print(from_client_cmd)
#通過subprocess模組執行服務端的系統指令,並且拿到指令執行結果
sub_obj = subprocess.popen(
from_client_cmd, #客戶端的指令
shell=true,
stdout=subprocess.pipe, #標準輸出:正確指令的執行結果在這裡
stderr=subprocess.pipe, #標準錯誤輸出:錯誤指令的執行結果在這裡
)#接受到的返回資訊是bytes型別的,並且windows系統的預設編碼為gbk
server_cmd_msg = sub_obj.stdout.read()
# server_cmd_err = sub_obj.stderr.read().decode('gbk')
#首先計算出你將要傳送的資料的長度
cmd_msg_len = len(server_cmd_msg)
#先對資料長度進行打包,打包成4個位元組的資料,目的是為了和你將要傳送的資料拼在一起,就好我們自定製了乙個訊息頭
msg_len_stru = struct.pack('i',cmd_msg_len)
conn.send(msg_len_stru) #首先傳送打包成功後的那4個位元組的資料
conn.sendall(server_cmd_msg) #迴圈send資料,直到資料全部傳送成功
import socketimport struct
client = socket.socket()
server_ip_port = ('192.168.15.113',8001)
client.connect(server_ip_port)
while 1:
msg = input('請輸入要執行的指令》')
client.send(msg.encode('utf-8'))
#先接收服務端要傳送給我的資訊的長度,前4個位元組,固定的
from_server_msglen = client.recv(4)
unpack_len_msg = struct.unpack('i',from_server_msglen)[0]
#接收資料長度統計,和服務端發給我的資料長度作比較,來確定跳出迴圈的條件
recv_msg_len = 0
#統計拼接接收到的資料,注意:這個不是統計長度
all_msg = b''
while recv_msg_len < unpack_len_msg:
every_recv_data = client.recv(1024)
#將每次接收的資料進行拼接和統計
all_msg += every_recv_data
#對每次接收到的資料的長度進行累加
recv_msg_len += len(every_recv_data)
print(all_msg.decode('gbk'))
解決粘包問題
要知道!所謂粘包問題主要還是因為接收方不知道訊息之間的界限,不知道一次性提取多少位元組的資料所造成的。要解決粘包不外乎乙個條件,就是知道取多少,讓對方事先知道我們要發多少位元組的資料,然後造乙個容器,每次規定的往容器裡面倒水,當水快滿的時候,量出最後一勺還需要多少勺多少的水,最後把這水不多不少的往容...
tcp解決粘包
tcp協議相對於udp協議的差別 tcp udp 是否連線 面向連線 面向非連線 傳輸可靠性 可靠 不可靠 應用場合 少量資料 傳輸大量資料 速度 慢 快 根據這個確定運用場合就好。tcp粘包原因 tcp協議的優化導致而成,也就是在多少毫秒內需要等到多少大小的快取內容,才會進行傳送,在 高併發模式下...
解決粘包現象
簡單版 服務端 usr bin env python coding utf 8 author mr.yang import socket import struct import subprocess phone socket.socket socket.af inet,socket.sock st...