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()返回運行程式所在的電腦的主機名
後言
寫部落格總結費時間,如果這篇博文對你有所幫助,記得給我點個贊哦🤞
參考文章鏈接

