目錄
1.能夠接收來自socket緩衝區的位元組資料;
2.當緩衝區沒有資料可以讀取時,recv會一直處於阻塞狀態,知道緩衝區至少有乙個位元組資料可取,或者客戶端關閉;
3.關閉遠端端並讀取所有資料後,再recv會返回字串。
應用層自定義協議ftp(檔案傳輸協議).
low版:
只能是有限的資料,將總資料長度固定成4個位元組作為報頭,再recv。當檔案資料特別大時,會報錯。
公升級版優點:
1. 自定製報頭。 如:dic =
2. 解決檔案資料過大問題。
把報頭做成字典,字典裡包含將要傳送的真實資料的描述資訊(大小啊之類的),然後json序列化,然後用struck將序列化後的資料長度打包成4個位元組。
我們在網路上傳輸的所有資料 都叫做資料報,資料報裡的所有資料都叫做報文,報文裡面不止有你的資料,還有ip位址、mac位址、埠號等等,其實所有的報文都有報頭,這個報頭是協議規定的。
思路:服務端:
1. 自定義報頭,字典形式,裡面存放檔案資訊等;
2. 然後將報頭字典 ——> json型別字串 ——> 編碼成 bytes型別資料;
3. 將報頭bytes型別的長度(len())——>固定成4個長度的位元組,然後再send();
4. 將報頭bytes型別的內容資料 send();
5. 再傳送總資料,如果資料量特別大時,迴圈讀取、傳送位元組。
客戶端:
1. 先收報頭固定長度,再struct,得到報頭資料的長度;
2. 根據長度接收報頭位元組資料,再解碼,反序列化成字典(json);
3. 從字典獲取檔案、資料的描述資訊(如檔名、大小等),再獲取真實的資料。
# 服務端
import socket
import subprocess
import struct
import json
phone = socket.socket()
phone.bind(('127.0.0.1',8888))
phone.listen(5)
while 1:
conn, addr = phone.accept()
print(f'與客戶端連線')
while 1:
try:
from_client_data = conn.recv(1024)
if from_client_data.upper() == b'q':
print('客戶端已退出!')
break
obj = subprocess.popen(from_client_data.decode("utf-8"),
shell=true,
stdout=subprocess.pipe,
stderr=subprocess.pipe,
)total_data = obj.stdout.read() + obj.stderr.read()
print(len(total_data))
head_dict = # 自定義報頭,字典型別
head_str = json.dumps(head_dict) # 報頭轉換成json的字串型別
head_bytes = head_str.encode('utf-8') # 報頭 轉換成 bytes 型別
head_len_bytes = struct.pack('i', len(head_bytes)) # 固定報頭 位元組數
conn.send(head_len_bytes) # 傳送報頭的 固定位元組
conn.send(head_bytes) # 傳送 報頭資料
conn.send(total_data) # 傳送 總資料, 可迴圈傳送檔案的資料
except connectionreseterror:
print('與客戶端連線中斷!')
break
conn.close()
phone.close()
# 客戶端
import socket
import struct
import json
phone = socket.socket()
phone.connect(('127.0.0.1', 8888))
while 1:
to_server_data = input('>>>').strip().encode('utf-8')
if not to_server_data:
print('內容不能為空!')
continue
phone.send(to_server_data)
if to_server_data.upper() == b'q':
break
head_len_bytes = phone.recv(4) # 接收報頭固定位元組長度
head_int = struct.unpack('i', head_len_bytes)[0] # 報頭長度反解成 int 長度
# print(head_int)
head_bytes = phone.recv(head_int) # 接收int長度的 報頭資料
head_dict = json.loads(head_bytes.decode('utf-8'))
# 將bytes型別的報頭 轉換成原型別(字典)
# print(head_dict['total_size'])
data = b''
while len(data) < head_dict['total_size']: # 小於檔案的大小,迴圈
data = data + phone.recv(1024)
print(len(data))
print(f"")
phone.close()
1. 基於udp協議的socket通訊無需建立管道,先開啟服務端或者客戶端都可以;
2. 基於udp協議的socket通訊,接收、傳送乙個訊息都是無連線的;
3. 只有拿到對方ip位址和埠就可以通訊發訊息,按照順序接收服務端訊息。
# 服務端
import socket
server = socket.socket(socket.af_inet, socket.sock_dgram)
server.bind(('127.0.0.1', 9000))
while 1:
client_data = server.recvfrom(1024)
# print(client_data)
data = client_data[0].decode('utf-8')
print(f'來自客戶端的訊息:')
to_data = input('>>>').encode('utf-8')
server.sendto(to_data, client_data[1])
# 客戶端
import socket
client = socket.socket(socket.af_inet, socket.sock_dgram)
# 基於網路的udp協議的socket
while 1:
to_server_data = input('>>>:').strip()
client.sendto(to_server_data.encode('utf-8'), ('127.0.0.1', 9000))
data, addr = client.recvfrom(1024)
print(f'來自服務端的訊息:')
24點(公升級版)
本24點 可以實現以下操作 查詢4個數經過 和 運算是否可得到nnn 支援僅查詢是否存在和查詢存在的算式 支援多組資料,每組資料結束後請按回車,當n 0 n 0n 0時結束 第一行乙個二進位制數g,0表示不輸出算式,1相反 輸入後過程中不可更改 接下來一行乙個數n nn然後下一行4個數,表示這些數參...
分糖果 5 0公升級版
題目描述 幼兒園裡有n個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww需要滿足小朋友們的k個要求。幼兒園的糖果總是有限的,lxhgww想知道他至少...
7 5 拯救007(公升級版)(30 分)
在老電影 007之生死關頭 live and let die 中有乙個情節,007被毒販抓到乙個鱷魚池中心的小島上,他用了一種極為大膽的方法逃脫 直接踩著池子裡一系列鱷魚的大腦袋跳上岸去!據說當年替身演員被最後一條鱷魚咬住了腳,幸好穿的是特別加厚的靴子才逃過一劫。設鱷魚池是長寬為100公尺的方形,中...