import
subprocess
res
= subprocess.Popen(
'
dir
'
,shell=True,stdout=subprocess.PIPE,stderr=
subprocess.PIPE)
print
(
'
Stdout:
'
,res.stdout.read().decode(
'
gbk
'
))
print
(
'
Stderr:
'
,res.stderr.read().decode(
'
gbk
'
))
PIPE把輸出的東西裝到一個'水管'里,如果在windows中的編碼格式是gbk,執行結果:
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/16 13:48
.
2019/09/16 13:48
..
2019/09/16 13:47
.idea
2019/09/16 13:46 21
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/16 13:48 207
Sever1.py
2019/09/16 01:41 70
time_test.py
2019/09/14 23:51
venv
4 個文件 298
字節
4 個目錄 45,863,636,992
可用字節
Stderr:
在這里也可以使用os.popen()但是它會不管正確和錯誤的結果都放在一起,而用subprocess能夠分別拿到正確和錯誤的信息
?
基于TCP實現的黏包
Sever:
import
socket
sk
=
socket.socket()
sk.bind((
'
127.0.0.1
'
,8092
))
sk.listen()
conn,addr
=
sk.accept()
while
True:
cmd
= input(
'
<<<
'
)
conn.send(cmd.encode(
'
gbk
'
))
ret
= conn.recv(1024).decode(
'
gbk
'
)
print
(ret)
conn.close()
sk.close()
Client:
import
socket
import
subprocess
sk
=
socket.socket()
sk.connect((
'
127.0.0.1
'
,8092
))
while
True:
cmd
= sk.recv(1024).decode(
'
gbk
'
)
ret
= subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=
subprocess.PIPE)
std_out
=
'
stdout:
'
+ (ret.stdout.read()).decode(
'
gbk
'
)
std_err
=
'
stderr:
'
+ (ret.stderr.read()).decode(
'
gbk
'
)
print
(std_out)
print
(std_err)
sk.send(std_out.encode(
'
gbk
'
))
sk.send(std_err.encode(
'
gbk
'
))
sk.close()
執行結果:
Sever:
<<<
dir;ls
stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
<<<
ipconfig
stderr:找不到文件
<<<
Client:
stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
stderr:找不到文件
stdout:
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
stderr:
當我們在sever端輸入dir;ls命令時,只有stdout的結果跑出來,而當我們輸入ipconfig這個命令時,系統將上一次dir;ls未執行完的stderr的結果給跑出來。像這樣沒有接受完全或者接受多了的就是黏包現象。
TCP會有黏包現象但是它不丟包。
?
基于UDP實現的黏包
Sever:
import
socket
sk
= socket.socket(type=
socket.SOCK_DGRAM)
sk.bind((
'
127.0.0.1
'
,8092
))
msg,addr
= sk.recvfrom(10240
)
while
1
:
cmd
= input(
'
<<<
'
)
if
cmd ==
'
q
'
:
break
sk.sendto(cmd.encode(
'
gbk
'
),addr)
msg,addr
= sk.recvfrom(10240
)
print
(msg.decode(
'
gbk
'
))
sk.close()
Client:
import
socket
import
subprocess
sk
= socket.socket(type=
socket.SOCK_DGRAM)
addr
= (
'
127.0.0.1
'
,8092
)
sk.sendto(
'
Start
'
.encode(
'
utf-8
'
),addr)
while
1
:
cmd,addr
= sk.recvfrom(10240
)
ret
= subprocess.Popen(cmd.decode(
'
gbk
'
),shell=True,stderr=subprocess.PIPE,stdout=
subprocess.PIPE)
std_out
=
'
Stdout:
'
+ (ret.stdout.read()).decode(
'
gbk
'
)
std_err
=
'
Stderr:
'
+ (ret.stderr.read()).decode(
'
gbk
'
)
print
(std_out)
print
(std_err)
sk.sendto(std_out.encode(
'
gbk
'
),addr)
sk.sendto(std_err.encode(
'
gbk
'
),addr)
sk.close()
執行結果:
Sever:
<<<
dir;ls
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
<<<
dir
Stderr:找不到文件
<<<
ipconfig
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/16 14:43
.
2019/09/16 14:43
..
2019/09/16 14:37
.idea
2019/09/16 14:43 553
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/16 14:43 306
Sever1.py
2019/09/16 01:41 70
time_test.py
2019/09/14 23:51
venv
4 個文件 929
字節
4 個目錄 45,855,449,088
可用字節
<<<
pwd
Stderr:
<<<
ip
Stdout:
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
<<<
Client:
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
Stderr:找不到文件
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/16 14:43
.
2019/09/16 14:43
..
2019/09/16 14:37
.idea
2019/09/16 14:43 553
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/16 14:43 306
Sever1.py
2019/09/16 01:41 70
time_test.py
2019/09/14 23:51
venv
4 個文件 929
字節
4 個目錄 45,855,449,088
可用字節
Stderr:
Stdout:
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
Stderr:
Stdout:
Stderr:
'
pwd
'
不是內部或外部命令,也不是可運行的程序
或批處理文件。
Stdout:
Stderr:
'
ip
'
不是內部或外部命令,也不是可運行的程序
或批處理文件。
可以看出UDP不會有黏包現象,會產生丟包現象,沒發完就不發了,不完整也不可靠。
?
黏包成因
TCP協議的數據傳送
拆包機制
當發送端緩沖區的長度大于網卡的MTU時,TCP會將這次發送的數據拆成幾個數據包發送出去。MTU是Maximum Transmission Unit的縮寫,意思是網絡上傳送最大數據包,MTU是字節單位,大部分網絡設備的MTU都是1500. 如果本機的MTU比網關的MTU大,大的數據包就會被拆開來傳送,這樣會產生很多數據包碎片,增加丟包率,降低網絡速度。
在正常情況下它的拆包可理解為:
面向流的通信特點和Nagle算法
TCP(transport control protocol,傳輸控制協議),是面向連接的,面向流的,提供高可靠性的服務。收發兩端(客戶端和服務端)都要有一一成對的socket,因此發送端為了將多個發往接收端的包,更有效地發往對方,使用了優化算法(Nagle算法),將多次間隔較小且數據量小的數據,合并成一個大的數據塊,然后進行封包。這樣接收端就難于分辨出來了,必須提供科學的拆包機制。即面向流的通信是無消息保護邊界的。
對于空消息:TCP是基于數據流的,于是收發消息不能為空,這就需要在客戶端和服務端都添加空消息的處理機制,防止程序卡住,而UDP協議是基于數據報的,即便是你輸入的是空內容(直接回車),也可以被發送,UDP協議會幫你封裝上消息然后發出去。
可靠黏包的TCP協議:TCP協議數據不會丟,沒有收完包,就會下次接收,會繼續上次繼續接受。
基于tcp協議特點的黏包現象成因
當我們在socket服務端發送值1、2,然后根據優化算法,它會把1先放到這個緩存當中等一等,然后再把2一起封裝起來,然后再發出去,因此我們看到的就是黏包現象
這種現象的表面現象是兩個send太近且發送的消息太短
發送端可以使1K1K地發送數據,而接收端的應用程序可以兩K兩K地提走數據,當然也有可能一次提走3K或6K數據,或者一次只提走幾個字節的數據。也就是說,應用程序所看到的數據是一個整體,或者說是一個流(stream),一條消息有多少字節對應程序是不可見的,因此TCP協議是面向流的協議,這也是容易出現黏包問題的原因。而UDP協議是面向消息的協議,每個UDP段都是一條消息,應用程序必須以消息單位提取數據,不能一次提取任意字節的數據,這一點和TCP是很不同的。
?
解決黏包的方法
解決方案一:
Sever:
import
socket
sk
=
socket.socket()
sk.bind((
'
127.0.0.1
'
,8080
))
sk.listen()
conn,addr
=
sk.accept()
while
True:
cmd
= input(
'
<<<
'
)
if
cmd ==
'
q
'
:
conn.send(b
'
q
'
)
break
conn.send(cmd.encode(
'
gbk
'
))
num
= conn.recv(1024).decode(
'
utf-8
'
)
conn.send(b
'
ok
'
)
res
= conn.recv(int(num)).decode(
'
gbk
'
)
print
(res)
conn.close()
sk.close()
Client:
import
socket
import
subprocess
sk
=
socket.socket()
sk.connect((
'
127.0.0.1
'
,8080
))
while
True:
cmd
= sk.recv(1024).decode(
'
gbk
'
)
if
cmd ==
'
q
'
:
break
res
= subprocess.Popen(cmd,shell=
True,
stdout
=
subprocess.PIPE,
stderr
=
subprocess.PIPE)
std_out
=
res.stdout.read()
std_err
=
res.stderr.read()
sk.send(str(len(std_out)
+ len(std_err)).encode(
'
utf-8
'
))
sk.recv(
1024
)
print
(
'
Stdout:
'
+ std_out.decode(
'
gbk
'
))
print
(
'
Stderr:
'
+ std_err.decode(
'
gbk
'
))
sk.send(std_out)
sk.send(std_err)
sk.close()
執行結果:
Sever:
<<<
dir
驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/17 15:33
.
2019/09/17 15:33
..
2019/09/17 15:31
.idea
2019/09/17 15:33 623
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/17 15:21 389
Sever1.py
2019/09/16 01:41 70
time_test.py
2019/09/14 23:51
venv
4 個文件 1,082
字節
4 個目錄 45,031,833,600
可用字節
<<<
ls
'
ls
'
不是內部或外部命令,也不是可運行的程序
或批處理文件。
<<<
ipconfig
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
<<<
Client:
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/17 15:33
.
2019/09/17 15:33
..
2019/09/17 15:31
.idea
2019/09/17 15:33 623
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/17 15:21 389
Sever1.py
2019/09/16 01:41 70
time_test.py
2019/09/14 23:51
venv
4 個文件 1,082
字節
4 個目錄 45,031,833,600
可用字節
Stderr:
Stdout:
Stderr:
'
ls
'
不是內部或外部命令,也不是可運行的程序
或批處理文件。
Stdout:
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
Stderr:
這種寫法的好處就是能確定Sever到底要接受多少數據,不好的地方就是多了一次交互
解決方案二: 使用struct模塊
用struct模塊我們能把一個數據類型轉換成固定長度的bytes
這里以數字類型舉例,'i'代表int類型:
import
struct
print
(struct.pack(
'
i
'
,2048),len(struct.pack(
'
i
'
,2048)))
#
b'\x00\x08\x00\x00' 4
print
(struct.pack(
'
i
'
,204800),len(struct.pack(
'
i
'
,204800)))
#
b'\x00 \x03\x00' 4
print
(struct.pack(
'
i
'
,2048000),len(struct.pack(
'
i
'
,2048000)))
#
b'\x00@\x1f\x00' 4
當后面的數值戳過一定范圍的時候程序就會報錯
Sever:
import
socket
import
struct
sk
=
socket.socket()
sk.bind((
'
127.0.0.1
'
,8080
))
sk.listen()
conn,addr
=
sk.accept()
while
True:
cmd
= input(
'
<<<
'
)
if
cmd ==
'
q
'
:
conn.send(b
'
q
'
)
break
conn.send(cmd.encode(
'
gbk
'
))
num
= conn.recv(4
)
num
= struct.unpack(
'
i
'
,num)[0]
res
= conn.recv(int(num)).decode(
'
gbk
'
)
print
(res)
conn.close()
sk.close()
Client:
import
socket
import
subprocess
import
struct
sk
=
socket.socket()
sk.connect((
'
127.0.0.1
'
,8080
))
while
True:
cmd
= sk.recv(1024).decode(
'
gbk
'
)
if
cmd ==
'
q
'
:
break
res
= subprocess.Popen(cmd,shell=
True,
stdout
=
subprocess.PIPE,
stderr
=
subprocess.PIPE)
std_out
=
res.stdout.read()
std_err
=
res.stderr.read()
len_num
= len(std_out) +
len(std_err)
num_by
= struct.pack(
'
i
'
,len_num)
print
(
'
Stdout:
'
+ std_out.decode(
'
gbk
'
))
print
(
'
Stderr:
'
+ std_err.decode(
'
gbk
'
))
sk.send(num_by)
sk.send(std_out)
sk.send(std_err)
sk.close()
執行結果:
<<<
dir
驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/17 16:25
.
2019/09/17 16:25
..
2019/09/17 16:23
.idea
2019/09/17 16:25 659
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/17 16:22 400
Sever1.py
2019/09/17 16:08 288
time_test.py
2019/09/14 23:51
venv
4 個文件 1,347
字節
4 個目錄 45,025,951,744
可用字節
<<<
configip
'
configip
'
不是內部或外部命令,也不是可運行的程序
或批處理文件。
<<<
ipconfig
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
<<<
Stdout: 驅動器 C 中的卷是 系統
卷的序列號是 85C0
-
669A
C:\Users\Administrator\PycharmProjects\Internet_program 的目錄
2019/09/17 16:25
.
2019/09/17 16:25
..
2019/09/17 16:23
.idea
2019/09/17 16:25 659
Client1.py
2019/09/16 13:42
0 Client2.py
2019/09/17 16:22 400
Sever1.py
2019/09/17 16:08 288
time_test.py
2019/09/14 23:51
venv
4 個文件 1,347
字節
4 個目錄 45,025,951,744
可用字節
Stderr:
Stdout:
Stderr:
'
configip
'
不是內部或外部命令,也不是可運行的程序
或批處理文件。
Stdout:
Windows IP 配置
以太網適配器 Bluetooth 網絡連接
2
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
以太網適配器 本地連接:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
無線局域網適配器 無線網絡連接:
連接特定的 DNS 后綴 . . . . . . . :
本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
8018%14
IPv4 地址 . . . . . . . . . . . . :
192.168.43.216
子網掩碼 . . . . . . . . . . . . :
255.255.255.0
默認網關. . . . . . . . . . . . . :
192.168.43.1
隧道適配器 本地連接
* 3
:
媒體狀態 . . . . . . . . . . . . : 媒體已斷開
連接特定的 DNS 后綴 . . . . . . . :
Stderr:
實現一個大文件的傳輸和下載
當我們在網絡上傳輸所有數據時,這些數據都叫數據包,數據包里的所有數據都叫報文,報文里不止有你的數據還有IP地址、MAC地址、端口號等,所有的報文都有報頭,這是由協議規定的。所有在網絡上傳播數據包的協議里都有一個報頭。什么時候需要自己定制報文?比如說復雜的應用上就會應用到、傳輸文件的時候(文件名、文件大小、文件類型、存儲路徑等)...
其實在網絡傳輸的過程當中處處有協議,協議就是一堆報頭和報文(都由字節組成)。
Sever:
import
socket
import
struct
import
json
buffer
= 1024
sk
=
socket.socket()
sk.bind((
'
127.0.0.1
'
,8080
))
sk.listen()
conn,addr
=
sk.accept()
head_len
= conn.recv(4
)
struct.unpack(
'
i
'
,head_len)[0]
json_head
= conn.recv(head_len).decode(
'
utf-8
'
)
head
=
json.loads(json_head)
file_size
= head[
'
fileSize
'
]
with open(r
'
dir\%s
'
%head[
'
fileName
'
],
'
wb
'
) as f:
while
file_size:
if
file_size >=
buffer:
content
=
conn.recv(buffer)
f.write(content)
file_size
-=
buffer
else
:
content
=
conn.recv(buffer)
f.write(content)
break
conn.close()
sk.close()
Client:
import
socket
import
struct
import
os
import
json
sk
=
socket.socket()
sk.connect((
'
127.0.0.1
'
,8080
))
buffer
= 1024
head
= {
'
filePath
'
: r
'
C:\Users\Administrator\Desktop\專題\海報資料夾\專題海報
'
,
'
fileName
'
: r
'
專題海報
'
,
'
fileSize
'
: None}
file_path
= os.path.join(head[
'
filePath
'
],head[
'
fileName
'
])
file_size
=
os.path.getsize(file_path)
head[
'
fileSize
'
] =
file_size
json_head
= json.dumps(head)
#
字典轉成字典
bytes_head = json_head.encode(
'
utf-8
'
)
#
字符串轉bytes
head_len
= len(bytes_head)
#
報頭的長度
pack_len = struct.pack(
'
i
'
,head_len)
sk.send(pack_len)
#
先發報頭的長度
sk.send(bytes_head)
#
再發bytes類型的報頭
with open(r
'
dir\%s
'
%file_path,
'
rb
'
) as f:
while
file_size:
if
file_size >=
buffer:
content
= f.read(buffer)
#
每次文件讀出的內容
sk.send(content)
file_size
-=
buffer
else
:
content
=
f.read(file_size)
sk.send(content)
break
sk.close()
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

