簡體   English   中英

Python Socket連接類

[英]Python Socket connection class

我正在嘗試創建一個小程序,它將通過TCP記錄從設備輸出的信息

基本上這只是流出數據,我想要捕獲,並轉儲到數據庫中以便稍后處理

但設備重新啟動,所以我需要能夠在插座關閉時重新連接,不受任何人為干擾

所以這就是我到目前為止所擁有的

import socket, time, logging, sys, smtplib                 # Import socket module

logging.basicConfig(filename='Tcplogger.log',level=logging.DEBUG,format='%(asctime)s : %(levelname)s : %(message)s')
logging.info('|--------------------------------------|')
logging.info('|--------------- TCP Logger Starting---|')
logging.info('|--------------------------------------|')


host = '127.0.0.01'           # host or Ip address
port = 12345                   # output port
retrytime = 1                  # reconnect time 
reconnectattemps = 10          # Number of time to try and reconnect 


class TPCLogger:
   def __init__(self):
       logging.debug('****Trying connection****')
       print('****Trying connection****')

       self.initConnection()


def initConnection(self):
    s = socket.socket()
    try:
        s.connect((host, port))
        logging.debug('****Connected****')
    except IOError as e:
        while 1:                
            reconnectcount = 0;
            logging.error(format(e.errno)+' : '+format(e.strerror))

            while 1:
                reconnectcount = reconnectcount + 1
                logging.error('Retrying connection to Mitel attempt : '+str(reconnectcount)) 
                try:
                    s.connect((host, port))                        
                    connected = True
                    logging.debug('****Connected****')
                except IOError as e:
                    connected = False
                    logging.error(format(e.errno)+' : '+format(e.strerror))
                    if reconnectcount == reconnectattemps:
                        logging.error('******####### Max Reconnect attempts reached logger will Terminate ######******')                                                        
                        sys.exit("could Not connect")
                    time.sleep(retrytime)
                if connected == True:
                    break
            break                                



    while 1:
        s.recv(1034)




LOGGER= TCPLogger()

如果嘗試連接並且不在那里,它在啟動時一切正常,它將重試由reconnectattemps設置的次數

但他是我的問題

    while 1:
        s.recv(1034)

當這個失敗時我想嘗試重新連接我當然可以鍵入或只是再次復制我的連接部分,但我希望能夠todo調用一個函數來處理連接並重試並將我交給連接對象

比如這樣

class tcpclient

#set some var
host, port etc....

def initconnection:
    connect to socket and retry if needed
    RETURN SOCKET

def dealwithdata:
    initconnection()
    while 1:
        try:
            s.recv
            do stuff here copy to db
         except:
             log error
             initconnection()

我認為這是可能的,但我真的不知道類/方法系統如何在python中工作,所以我想我在這里遺漏了一些東西

僅供參考,以防你沒注意到我對python非常新。 我已經擁有的任何其他評論也歡迎:)

謝謝Aj

您應該查看python文檔以了解類和方法的工作方式。 大多數其他語言中python方法和方法之間的最大區別是添加了“self”標記。 self表示調用方法的實例,並由python系統自動輸入。 所以:

class TCPClient():

    def __init__(self, host, port, retryAttempts=10 ):
        #this is the constructor that takes in host and port. retryAttempts is given 
        # a default value but can also be fed in.
        self.host = host
        self.port = port
        self.retryAttempts = retryAttempts
        self.socket = None

    def connect(self, attempt=0):
        if attempts<self.retryAttempts:
            #put connecting code here
        if connectionFailed:
            self.connect(attempt+1)

    def diconnectSocket(self):
        #perform all breakdown operations
        ...
        self.socket = None

    def sendDataToDB(self, data):
        #send data to db

    def readData(self):
        #read data here
        while True:
            if self.socket is None:
                self.connect()
            ...

只需確保正確斷開套接字並將其設置為無。

建議

對於這個用例,我會推薦比套接字更高級的東西。 為什么? 當您只想檢索或發送數據並保持連接時,自行控制所有這些異常和錯誤可能會令人惱火。

當然,你可以通過簡單的解決方案實現你想要的東西,但是你會更多地使用代碼。 無論如何,它看起來類似於類amustafa寫的,處理套接字錯誤以關閉/重新連接方法等。

我使用asyncore模塊為更簡單的解決方案做了一些示例:

import asyncore
import socket
from time import sleep

class Client(asyncore.dispatcher_with_send):
    def __init__(self, host, port, tries_max=5, tries_delay=2):
        asyncore.dispatcher.__init__(self)
        self.host, self.port = host, port

        self.tries_max = tries_max
        self.tries_done = 0
        self.tries_delay = tries_delay

        self.end = False # Flag that indicates whether socket should reconnect or quit.
        self.out_buffer = '' # Buffer for sending.

        self.reconnect() # Initial connection.

    def reconnect(self):
        if self.tries_done == self.tries_max:
            self.end = True
            return

        print 'Trying connecting in {} sec...'.format(self.tries_delay)
        sleep(self.tries_delay)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.connect((self.host, self.port))
        except socket.error:
            pass

        if not self.connected:
            self.tries_done += 1
            print 'Could not connect for {} time(s).'.format(self.tries_done)


    def handle_connect(self):
        self.tries_done = 0
        print 'We connected and can get the stuff done!'

    def handle_read(self):
        data = self.recv(1024)
        if not data:
            return

        # Check for terminator. Can be any action instead of this clause.
        if 'END' in data:
            self.end = True # Everything went good. Shutdown.
        else:
            print data # Store to DB or other thing.

    def handle_close(self):
        print 'Connection closed.'
        self.close()

        if not self.end:
            self.reconnect()

Client('localhost', 6666)

asyncore.loop(timeout=1)

reconnnect()方法在某種程度上是你的案例的核心 - 當需要建立連接時調用它:當類初始化或連接斷開時。 handle_read()操作任何收到的數據,在這里你記錄它或什么。 您甚至可以使用緩沖區( self.out_buffer += 'message' )發送數據,重新連接后它將保持不變,因此當再次連接時,類將繼續發送。 self.end設置為True將通知類在可能的情況下退出。

asyncore負責處理異常並在發生此類事件時調用handle_close() ,這是處理連接失敗的便捷方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM