Python Socket连接类

时间:2013-07-31 06:49:34

标签: python class function sockets python-3.x

我正在尝试创建一个小程序,它将通过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

2 个答案:

答案 0 :(得分:1)

您应该查看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()
            ...

只需确保正确断开套接字并将其设置为无。

答案 1 :(得分:1)

建议

对于这个用例,我建议使用比套接字更高级别的东西。为什么?当您只想检索或发送数据并保持连接时,自行控制所有这些异常和错误可能会令人恼火。

当然,你可以通过简单的解决方案实现你想要的东西,但是你会更多地使用代码。无论如何,它看起来类似于类 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(),这是处理连接失败的便捷方法。