網路程式設計基礎【day09】:socket接收大資料(五)
阿新 • • 發佈:2018-11-02
本節內容
1、概述
2、socket接收大資料
3、中文字元的坑
一、概述
上篇部落格寫到了,就是說當伺服器傳送至客戶端的資料,大於客戶端設定的資料,則就會把資料服務端發過來的資料剩餘資料存在IO緩衝區中,那我們如何解決這個問題呢?
有的同學就說了:
- 改大客戶端接收的資料的大小=>這個方案並不能解決問題,因為官方建議最多隻能接收8k的資料,那服務端傳送過來的資料大於8K咋辦,很顯然不行
- 客戶端可以多收幾次=>客戶端需要收多少次,才能把這個命令返回的結果全部收回來呢?並且怎麼確定這條命令返回的結果已經被全部收回來了呢?
很明顯,上面第二種思路靠譜一點:就是說服務端給客戶端發資料之前,先計算一下給客戶端要發多少資料,我先判斷 len 一下,就 ok 了,先讓客戶端知道服務端傳送過來的大小,比如說發過來的是5k大小,客戶端接收到了這個5k大小以後,就知道需要接收多少次了,迴圈接收,直到5k資料全部接收完畢為止。
二、socket接收大資料
2.1、邏輯圖
2.2、邏輯程式碼
1、客戶端程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import
socket
client
=
socket.socket()
client.connect((
"localhost"
,
9999
))
while True
:
cmd
=
input
(
">>>:"
).strip()
if
len
(cmd)
=
=
0
:
continue
client.send(cmd.encode(
"utf-8"
))
cmd_res_size
=
client.recv(
1024
)
#接收命令的長度
print
(
"命令結果大小:"
,cmd_res_size.decode())
recevied_size
=
0
#接收客戶端發來資料的計算器
recevied_data
=
b''
#客戶端每次發來內容的計數器
while
recevied_size <
int
(cmd_res_size.decode()):
#當接收的資料大小 小於 客戶端發來的資料
cmd_res
=
client.recv(
1024
)
recevied_size
+
=
len
(cmd_res)
#每次收到的服務端的資料有可能小於1024,所以必須用len判斷
recevied_data
+
=
cmd_res
else
:
print
(recevied_data.decode(
"utf-8"
,
"ignore"
))
print
(
"cmd res receive done ...."
,recevied_size)
client.close()
|
2、服務端程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import
socket,os
server
=
socket.socket()
server.bind((
"localhost"
,
9999
))
server.listen(
5
)
while
True
:
conn,addr
=
server.accept()
print
(
"new addr:"
,addr)
while
True
:
data
=
conn.recv(
1024
)
if
not
data:
print
(
"客戶端已斷開"
)
break
print
(
"執行指令:"
,data)
cmd_res
=
os.popen(data.decode()).read()
print
(
"before send:"
,
len
(cmd_res))
if
len
(cmd_res)
=
=
0
:
cmd_res
=
"cmd has no output...."
conn.send(
str
(
len
(cmd_res.encode())).encode() )
#傳送服務端傳送給客戶端資料的長度
conn.send(cmd_res.encode(
"utf-8"
))
#傳送服務端的資料
print
(
"send done"
)
server.close()
|
上面的程式碼解決了上面部落格,客戶端接收大資料出現的疑難雜症,問題表現,請檢視:猛擊這裡 中的 socket接收大資料困惑。
三、中文字元的坑
3.1、客戶端接收資料大小和實際大小不一致
說明:客戶端在接收資料的大小會和實際資料帶下不一樣,感覺實際資料要比客戶端接收的資料要大,這是為什麼呢?我們先來看一下現象吧。
1、客戶端程式碼改動如圖:
2、服務端程式碼改動如圖:
3、實現的效果圖:
上面的兩個資料應該一樣的呀,為啥不一樣呢?為啥之前的就能一樣呢?
答:因為python用計算中文字元,按字元和位元組算的話,長度的值是不一樣的,一個 中文字元=3個位元組 ,如圖: