Linux開發板(樹莓派)和服務器進行雙向通信(socket)


前言

​ 物聯網是目前嵌入開發必備的屬性之一,我們常常需要把自己開發板和雲端進行交互,本篇博文就記錄一下。

​ 使用Socket來實現Linux開發板和服務器進行雙向通信,Python中是默認集成了socket模塊的,我們就不需要下載了。

​ 實際上,只要是能運行Python的環境,就可以和服務器進行雙向通信,你不必局限於樹莓派。

一、開發環境

PC系統:windows 10

Linux開發板:樹莓派4B

服務器:阿里雲 ECS

編程語言:Python

二、通信代碼

​ 我認為我的注釋是十分詳細的,實現簡單用函數來調用(貼代碼方便),自己開發時,可以用類封裝一下。

記得先在服務器把要用的端口添加到安全組里面。下面的代碼服務器端你不需要做任何修改,開發板端你把公網ip修改成自己的就可以跑通了。

(1)服務器端
import socket
import sys


def socket_service_data():
    # 連接
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(ADDR)  # 在不同主機或者同一主機的不同系統下使用實際ip
        s.listen(10)
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    print("Wait for Connection..................")
	sock, addr = s.accept()
    
    while True:
        # 收
        buf = sock.recv(BUFSIZ)  # 接收數據
        buf1 = buf.decode('utf-8')  # 解碼
        if not buf:
            break
        print('Received message:', buf1)
        # return buf
        # 發
        buf = input("input data:")  # 輸入要傳輸的數據
        if not buf:
            break
        sock.send(buf.encode())  # 將要傳輸的數據編碼發送,如果是字符數據就必須要編碼發送
    # 關閉socket
    sock.close()


if __name__ == '__main__':
    # 初始化
    name = socket.gethostname()
    HOST = socket.gethostbyname(name)  # 獲取阿里雲服務器私網IP,使用ifconfig可查詢
    PORT = 7000
    BUFSIZ = 1024
    ADDR = (HOST, PORT)

    socket_service_data()

(2)開發板端
import socket
import sys


def sock_client_data():
    # 連接
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(ADDR)
    except socket.error as msg:
        print(msg)
        print(sys.exit(1))

    while True:
        # 發
        data = input("input data:")  # 輸入要傳輸的數據
        if not data:
            break
        s.send(data.encode('utf-8'))  # 將要傳輸的數據編碼發送,如果是字符數據就必須要編碼發送
        # 收
        data = s.recv(BUFSIZ)
        if not data:
            break
        print(data.decode('utf-8'))
    # 關閉socket
    s.close()


if __name__ == '__main__':
    # 初始化
    HOST = '99.100.101.102'  # 比如 99.100.101.102是你的服務器的公網IP
    PORT = 7000  # IP開放的socket端口
    BUFSIZ = 1024
    ADDR = (HOST, PORT)

    sock_client_data()

開發板發一句,服務器接受一句,服務器發一句,開發板再接受一句。

三、通信代碼解釋

​ 代碼邏輯沒什么說的,簡單說下socket模塊中調用的一下方法。

1.sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

:socket.AF_INET IPv4(默認),socket.SOCK_STREAM 流式socket , for TCP (默認),缺省是0 我上面都沒填系統就會根據地址格式和套接類別,自動選擇一個合適的協議。

2.sk.bind(address)

:s.bind(address) 將套接字綁定到地址。address地址的格式取決於地址族。

在AF_INET下,以元組(host,port)的形式表示地址。

3.sk.listen(backlog)

:開始監聽傳入連接。backlog指定在拒絕連接之前,可以掛起的最大連接數量。backlog等於5,表示內核已經接到了連接請求,但服務器還沒有調用accept進行處理的連接個數最大為5。這個值不能無限大,因為要在內核中維護連接隊列。

4.sk.accept()

:接受連接並返回(conn,address),其中conn是新的套接字對象,可以用來接收和發送數據。address是連接客戶端的地址。接收TCP 客戶的連接(阻塞式)等待連接的到來。

5.sk.connect(address)

:連接到address處的套接字。一般,address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。

6.sk.recv(bufsize[,flag])

:接受套接字的數據。數據以字符串形式返回,bufsize指定最多可以接收的數量。flag提供有關消息的其他信息,通常可以忽略。

7.sk.send(string[,flag])

:將string中的數據發送到連接的套接字。返回值是要發送的字節數量,該數量可能小於string的字節大小。即:可能未將指定內容全部發送。

8.sk.close()

:關閉套接字

9.socket.gethostname()

:gethostname()返回運行程序所在的計算機的主機名

后言

如果有相關的問題,歡迎在評論區交流,博主知必答。

參考文章鏈接

樹莓派4B和阿里雲服務器進行通信

網絡編程-Python的socket庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM