用struct模組實現python socket收發自訂TCP包

來源:互聯網
上載者:User

標籤:python   socket   struct模組   

最近跳槽到西安一家機器人公司,我們的產品屬於教育機器人的範疇,為了增強客戶吸引力,引進了一個智能家居公司的產品API介面,讓機器人來操作智能家居


該公司的智能家居API是自訂TCP包,即直接在TCP頭後面寫自訂資料結構:

用戶端請求下載 傢具資料庫 的格式

命令字(4位元組,小端)

0x4c

伺服器返回請求結果 的格式

命令字(4位元組,小端) payload長度(4位元組,小端) payload(N*1位元組)
0x43 11262(尺寸很大) sqlite資料庫


預設python socket只能收發字串,需要藉助struct才能收發位元據


發送請求

cmd_word = 0x4ctx_buf = struct.pack('<I', cmd_word)sock.sendall(tx_buf)

tx_buf據struct的文檔說是其對輸入編碼產生的字串,用type(tx_buf)顯示確實是<type ‘str‘>,print tx_buf顯示字母L

但len(tx_buf) == 4, print repr(tx_buf)顯示

‘L\x00\x00\x00‘

也就是說len(‘L\x00\x00\x00‘) == 4

對於從C語言轉過來的人來說,上面情況真是理解不能,但它就是發送成功了


接收應答

fp = open('house.db', 'wb+')recv_cnt = 0while True:    rx_buf = sock.recv(4096)    len_buf = len(rx_buf)    if len_buf ==0:        break    if recv_cnt == 0:        cmd_word, data_len_total = struct.unpack(rx_buf[0:8])        buf = buffer(rx_buf, 8, len_buf - 8)        fp.write(buf)    else:        buf = buffer(rx_buf)        fp.write(buf)    recv_cnt = recv_cnt +1

注意:

0、接收自訂幀頭時用unpack,可以獲得結構體各欄位取值

1、接收自訂幀內容(位元組流)時不用unpack,因為unpack返回的是tuple,而write不支援tuple類型

2、因為是二進位寫入,所以必須將str轉成buffer類型

3、位元據很大時,底層會拆分成多個乙太網路幀,如果你sendall後馬上recv,則可能只收到1448位元組,不要擔心,這是因為你recv時核心協議棧只有一幀這麼多資料,它全部返回給你了,滿足socket編程的標準








用struct模組實現python socket收發自訂TCP包

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.