2014-10-19 151 views
2

我已經在Python中使用套接字類做了大量的研究,但是我很難理解如何實現我的問題的解決方案。讓我也清楚地說,我對Python語言絕對沒有經驗。我已經湊到一起的代碼是來自其他幾個例子。它主要起作用,我只想找出最後一個錯誤。Python套接字 - 處理客戶端斷開連接

想法是這個腳本將運行在覆盆子pi上,這將是Pi的唯一目的。通過TCP,您將請求圖像編號,並且Pi將全屏顯示該特定圖像。很簡單,對吧?

再說一遍,除非客戶端的以太網連接被切斷,或者客戶端關閉了連接,否則一切都有效。然後腳本進入一個壞的無限循環,CPU使用率最大化,並且我別無選擇,只能物理地使PI循環。我需要一種方法來確保不會發生這種情況,並且在出現斷開連接/網絡故障等情況時,客戶端可以重新建立與此服務器的連接。

這是我到目前爲止。

import sys 
import pygame 
import SocketServer 

pygame.init() 
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN, 0) 
pygame.mouse.set_visible(False) 
imagesequence = [] 
imagesequence.append(pygame.image.load("/home/pi/appfiles/image1.png") 
imagesequence.append(pygame.image.load("/home/pi/appfiles/image2.png") 

screensaver = [] 
screensaver.append(pygame.image.load("/home/pi/appfiles/screensaver1.png") 

class MyTCPHandler(SocketServer.StreamRequestHandler): 
    def handle(self): 
     while True: 
      self.data = self.rfile.readline().strip() 

      isNum = False 

      try: 
       int(self.data) 
       isNum = True 
      except ValueError: 
       isNum = False 

      if isNum: 
       framenumber = int(self.data) 
       if framenumber >= 1 and framenumber <= len(imagesequence): 
        screen.blit(imagesequence[framenumber-1], (0,0)) 
        pygame.display.flip() 
       elif framenumber >= 901 and framenumber <= 900+len(screensaver): 
        screen.blit(screensaver[framenumber-901], (0,0)) 
        pygame.display.flip() 
      else: 
       if self.data == "q": 
        pygame.quit() 
        server.shutdown() 

if __name__ == "__main__": 
    HOST, PORT = "192.168.1.51", 5050 

    SocketServer.TCPServer.allow_reuse_address = True 
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) 

    server.serve_forever() 

通過TCP連接退出腳本也不起作用,但我並不那麼擔心。最終,永遠不會有理由放棄這一點。

回答

1

self.rfile.readline()返回空字符串''當插座連接被關閉。不過,請確保在應用.strip()之前檢查它,因爲發送空白字符串在刪除空格後看起來像空字符串。

import socketserver 

class MyTCPHandler(SocketServer.StreamRequestHandler): 
    def handle(self): 
     while True: 
      self.data = self.rfile.readline() 
      if not self.data: 
       break 
      self.data = self.data.strip() 
      ... 
+0

好吧,現在我們正在某個地方。因此,如果它打破了,服務器仍應保持活動狀態,仍然接受傳入連接,對嗎? AKA,客戶端可以重新連接沒有問題。 – BHelman 2014-10-19 12:52:53

+0

是的,爲每個客戶端連接調用一次「句柄」。如果你的服務器來自'ThreadingTCPServer',你甚至可以同時擁有客戶端。 – 2014-10-19 17:43:30

0

無情的代碼挖掘後,我無法回答第一部分。看起來在這個高級別上沒有辦法檢測到套接字關閉。看看(不受歡迎,我認爲,但完全可用)asyncore和asynchat模塊。

至於第二部分,你需要在收到'q'時從循環中斷開。

舌臉頰代碼示例中:

break 
+0

呵呵,我很欣賞這個例子和你的努力。第二部分我應該更具體些。我遇到的特殊問題是pygame沒有正確退出。一旦腳本全屏顯示,即使退出後,它也將永遠保持黑色全屏。我無法回到Bash的生活中。但是,是的,我應該包括一個良好形式的休息。 – BHelman 2014-10-19 12:55:31