網路程式設計(六) 自定義報頭

2022-05-17 02:28:06 字數 2891 閱讀 1099

*****

當你正在給你朋友顯擺你的**的時候, 飄過來乙個大神隨口說道:「這**有問題」

大神說的話不能不當真啊,誰讓你是個菜雞,你仔細想了一會兒。嗯,確實有問題

首先,我剛才做的報頭,按照協議來說應該不只有長度資訊,還應該有其他資訊

其次就是這個struct模組,它是有長度範圍限制的

struct.pack("i", 10000000000)
這樣就會報錯,因為你超過他長度了

struct.pack("l", 10000000000)
這樣就不會報錯了,但是當我後面的數字是100000000000000000,還是報錯了

所以要針對這兩點,優化一下**,也就是自定義報頭

那別的地方都不用改動,我們就看報頭部分就行

首先報頭部分的資訊用什麼型別來儲存呢?最好是字典,因為字典有明確的對映關係

dic =
好,字典就設定好了!但是,字典型別能用於資料傳輸嗎?

肯定是不能的啊,所以要把字典轉換成為位元組模式才行

那要是這樣的話,我就想到了序列化!

head = json.dumps(dic)
json格式的字串,能用來傳送嗎?不能

所以還要編碼一下

head = head.encode("gbk")
然後就想到了struct模組了,但是她只能接收數字是吧,所以我們可以把報頭的長度發過去

struct.pack("i", len(head))
然後再把報頭的資訊發過去

connet.send(head)
最後再發真實資料,那服務端大概就是這樣做的

那客戶端呢????

我應該先解碼,然後反序列化,然後拿到的是字典

最後再通過字典來進行取值操作

那經過上面的分析,我們可以對**進行如下修改!

# 服務端

import json

import socket

import struct

import subprocess

# 買手機

phone = socket.socket(socket.af_inet, socket.sock_stream)

# 繫結手機卡

phone.bind(("127.0.0.1", 8080))

phone.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1)

# 開機

phone.listen(5)

# 等**

connet, client_addr = phone.accept()

# 收發訊息

while 1:

try:

k = connet.recv(1024)

obj = subprocess.popen(k.decode("gbk"), shell=true, stdout=subprocess.pipe, stderr=subprocess.pipe)

stdout = obj.stdout.read()

stderr = obj.stderr.read()

dic =

head = json.dumps(dic)

head = head.encode("gbk")

res = struct.pack("i", len(head))

connet.send(res)

connet.send(head)

connet.send(stdout)

connet.send(stderr)

except connectionreseterror:

break

# 掛**

connet.close()

# 關機

phone.close()

# 客戶端

import json

import socket

# 買手機

import struct

phone = socket.socket(socket.af_inet, socket.sock_stream)

# 撥號

phone.connect(("127.0.0.1", 8080))

# 發收資訊

while 1:

msg = input(">>>")

phone.send(msg.encode("gbk"))

res = phone.recv(4)

re_msg = struct.unpack("i", res)[0]

msg = phone.recv(re_msg)

msg = msg.decode("gbk")

msg = json.loads(msg)

re_len = msg["file_size"]

re_size = 0

r = b"" # 我傳過來的是位元組模式

while re_size < re_len:

k = phone.recv(1024)

r += k

re_size += len(k)

print(re_size, re_len)

print(f'從服務端接收的訊息:')

connet.close()

# 關閉

phone.close()

這樣我們的這個c/s架構模式就基本成型了

以後的c/s架構就可以仿照這個模式來進行

至此,關於粘包問題的解決方案就告一段落了

*模板嘛*

*實在不行記下來嘛*

自定義http報頭 HTTP報文

超文字傳輸協議 http協議在規範文件裡詳細定義了報文的格式,規定了組成部分,解析規則,還有處理策略,所以可以在 tcp ip層之上實現更靈活豐富的功能,例如連線控制,快取管理 資料編碼 內容協商等等。報文結構 拿tcp報文來舉例,它在實際要傳輸的資料之前附加了乙個20位元組 的頭部資料,儲存tcp...

自定義協議 你也可以自定義報頭協議

在學習過計算機網路的課程,我們知道剛開始計算機都是單獨離線工作的,沒有聯網的情況下計算機的資訊共享能力 運算能力都非常有限,後來誕生了計算機網路.有了就是那幾網路,計算機 a 的資訊和資料可以通過網路傳遞到計算機 b,同樣計算機 a 可以獲取到來自計算機 b 的資料.但是不同計算機之間交換資料的時候...

網路程式設計 自定義程序類

建立自定義程序類 編寫類繼承process 在自定義類中載入父類 init 以獲取父類屬性,同時可以自定義新的屬性 重寫run方法,在呼叫start時自動執行該方法 from multiprocessing import process import time class clockprocess ...