在flask裡加socket進行底層通訊

2021-10-04 06:06:44 字數 3557 閱讀 5304

想在flask編寫的伺服器程式實現這樣乙個功能,與底層硬體通訊。底層硬體是網路介面,通過tcp/udp協議進行資料傳輸。因此伺服器需要使用socket。然而flask的socket是websocket,它雖然從socket衍生出來,但僅用於與客服端進行資料互動。怎麼辦?

@socketio.on(

'needdata'

)def

onneeddata()

: sock=socket.socket(socket.af_inet, socket.sock_stream)

#建立乙個socket

sock.connect(hardware_addr)

#連線到硬體

sock.send(cmd)

#向硬體傳送指令

data=sock.recv(

1024

)#接收硬體的資料

socketio.emit(

"givedata"

,data)

#發給客戶端

對於上圖中的通訊b很容易搞定,下面主要是解決通訊a的問題。

基本的socket服務端程式

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

#新建socket

sock.bind(address)

#繫結位址

sock.listen(30)

connection, addr=sock.accept(

)#等待客戶端傳送訊息,此時程式阻塞在這,如果收到訊息會往下執行。

msg=connection.recv(

1024

)#通過新生成的connection來接收訊息,connection也是乙個socket

connection.sendto(data,client_address)

#通過新生成的connection來傳送資料

可處理多個連線的socket服務端程式

基本的用法只能一次接收乙個客戶端的連線,並且也程式也有阻塞,若沒收到訊息,則程式一直原地踏步。要處理多個連線,可以設定乙個主迴圈,來不斷的接收訊息,還不斷的傳送資料,並且同時處理多個連線。

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

#新建socket

sock.setblocking(

false

)#設定成非阻塞

sock.bind(address)

#繫結位址

sock.listen(30)

client=

#客戶的列表

while

true

:if stop():

#退出迴圈

break

try:

connection, addr=sock.accept(

)(connection,addr)

)except blockingioerror:

#有阻塞異常,可以pass掉

pass

for c_socket,c_addr in client_list:

try:

msg=c_socket.recv(

1024

)#接收資料

except

(blockingioerror, connectionreseterror)

:pass

c_socket.sendto(data,c_addr )

#傳送資料

#清理連線到客戶端的socket

for c_socket,c_addr in client_list:

c_socket.close(

) client_list.remove(

(c_socket,c_addr)

)sock.close(

)#關閉伺服器的socket

socket加執行緒

flask框架其實也有乙個大迴圈,兩個大迴圈要合併的話,就需要通過執行緒來實現。將通訊a的socket放到執行緒裡,可以將socket的連線客戶端的程式做乙個執行緒,接收資料又是乙個執行緒。

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

sock.setblocking(

false

)#設定成非阻塞

client=

#連線線程

defconnect()

:while

true

:if stop():

break

try:

connection, addr=sock.accept(

)(connection, addr)

)print

("接收到新模組 其位址為:"

,addr,

"目前模組有"

,len

(client)

,"個"

)except blockingioerror:

pass

defreceive()

:while

true

:if stop():

break

for c_socket,c_addr in client:

try:

msg=c_socket.recv(

1024

)except

(blockingioerror, connectionreseterror)

:pass

'/')

defindex()

: sock.bind(server_address)

sock.listen(30)

heartbeat(

) connect_run=threading.thread(target=connect)

#連線客戶端執行緒

receive_run=threading.thread(target=receive)

#接收資料執行緒

connect_run.start(

)#啟動連線客戶端執行緒

receive_run.start(

)#啟動接收資料執行緒

return render_template(

'index.html'

)#開啟flask伺服器

if __name__==

"__main__"

:true

, host=server_ip, port=server_port)

for c_socket,c_addr in client:

c_socket.close(

) client.remove(

(c_socket,c_addr)

) sock.close(

)

需要注意的是socket的bind函式和listen函式必須在flask裡面的某個路徑函式裡,如果放在開啟flask前面就開啟執行緒,則flask無法開啟,具體原因正在查明

delphi在TreeView 裡加核取方塊

這裡是建立乙個乙個類 type tcheckboxtreeview class ttreeview protected procedure createparams var params tcreateparams override end 具體只要加一句話 procedure tcheckboxt...

Android開啟熱點通過socket進行檔案傳輸

下面直接看 開啟socket public void click2 view view catch exception e if serversocket null catch ioexception e start 服務端傳送訊息 private class handlerthread imple...

在servlet專案裡加入並開啟html頁面

老師課件上用了index.html頁面開啟了servlet的doget和dopost方法,但我一直是404。一開始我把.html放在根目錄下,打不開 後來網上說在web.xml的 welcome file list 加上 welcome file web inf index.html welcome...