[英]Simplest, easiest way for 2 Python scripts on 2 computers over local network to share data
[英]Simplest python network messaging
我有一個Python的機器控制系統,目前看起來大致如此
goal = GoalState()
while True:
current = get_current_state()
move_toward_goal(current,goal)
現在,我正試圖增加通過網絡控制機器的能力。 我想寫的代碼是這樣的:
goal = GoalState()
while True:
if message_over_network():
goal = new_goal_from_message()
current = get_current_state()
move_toward_goal(current,goal)
將這種網絡功能添加到我的應用程序中最簡單,最Pythonic的方法是什么? 套接字可以工作,認為他們並不特別感覺Pythonic。 我看過XMLRPC和Twisted,但兩者似乎都需要對代碼進行重大修改。 我也看過ØMQ,但感覺我正在添加一個外部依賴項,它沒有提供任何我沒有使用套接字的東西。
我並不反對使用我上面提到的任何系統,因為我認為失敗可能是我的誤解。 我只是好奇地處理這個簡單,常見的問題的慣用方法。
至少有兩個問題你需要決定:
關於1. TCP套接字是最低級別,您需要處理低級別的事情,如識別消息邊界。 此外,只要連接未重置(由於例如臨時網絡故障),TCP連接就可以為您提供可靠的交付。 如果希望應用程序在TCP連接重置時正常恢復,則需要實現某種形式的消息確認,以跟蹤需要通過新連接重新發送的內容。 OMQ為您提供比純TCP連接更高級別的抽象。 您不需要處理字節流,但需要處理整個消息。 它仍然不能為您提供可靠的交付,消息可能會丟失,但它提供了幾種可用於確保可靠交付的通信模式。 0MQ也是高性能的,IMO是一個不錯的選擇。
關於2,如果不需要與其他語言的互操作性,那么Pickle是一種非常方便和Pythonic的選擇。 如果需要互操作性,您可以考慮JSON,或者,如果性能有問題,可以考慮二進制格式,例如Google協議緩沖區。 這最后的選擇需要最多的工作(你需要在.idl文件中定義消息格式)這絕對不會感覺到Pythonic。
看一下普通套接字上的消息交換(任何可序列化的Python對象)如何看起來像:
def send(sockfd, message):
string_message = cPickle.dumps(message)
write_int(sockfd, len(string_message))
write(sockfd, string_message)
def write_int(sockfd, integer):
integer_buf = struct.pack('>i', integer)
write(sockfd, integer_buf)
def write(sockfd, data):
data_len = len(data)
offset = 0
while offset != data_len:
offset += sockfd.send(data[offset:])
還不錯,但正如你所看到的,必須處理消息長度的序列化是相當低的水平。
並收到這樣的消息:
def receive(self):
message_size = read_int(self.sockfd)
if message_size == None:
return None
data = read(self.sockfd, message_size)
if data == None:
return None
message = cPickle.loads(data)
return message
def read_int(sockfd):
int_size = struct.calcsize('>i')
intbuf = read(sockfd, int_size)
if intbuf == None:
return None
return struct.unpack('>i', intbuf)[0]
def read(sockfd, size):
data = ""
while len(data) != size:
newdata = sockfd.recv(size - len(data))
if len(newdata) == 0:
return None
data = data + newdata
return data
但這並沒有優雅地處理錯誤(沒有嘗試確定哪些消息成功傳遞)。
如果您熟悉套接字,我會考慮使用SocketServer.UDPServer
(請參閱http://docs.python.org/library/socketserver.html#socketserver-udpserver-example )。 UDP絕對是最簡單的消息傳遞系統,但顯然,您必須處理某些消息可能丟失,重復或無序傳遞的事實。 如果您的協議非常簡單,那么它的處理起來相對容易。 優點是您不需要任何其他線程,也不需要外部依賴項。 如果您的應用程序沒有會話概念,它也可能是非常好的選擇。
一開始可能會有好處,但還有更多細節需要考慮,不包括在你的問題中。 我也不會擔心插座不是非常Pythonic的事實。 無論如何,你最終會使用套接字,有人會為你包裝它們,你將被迫學習框架,在最好的情況下可能會滿足你的要求。
(請注意我的觀點非常偏頗,因為我喜歡處理原始套接字。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.