想在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...