Python套接字连接类

Python套接字连接类,python,class,function,sockets,python-3.x,Python,Class,Function,Sockets,Python 3.x,我正在尝试创建一个小程序,它将记录通过TCP从设备输出的信息 基本上,这只是将我想要捕获的数据流出来,然后转储到数据库中,以便以后处理 但是设备会重新启动,所以我需要能够在插座关闭时重新连接,而不会受到任何人为干扰 这就是我目前所知道的 import socket, time, logging, sys, smtplib # Import socket module logging.basicConfig(filename='Tcplogger.log',lev

我正在尝试创建一个小程序,它将记录通过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()
这一切在启动时都可以正常工作如果尝试连接但不在那里,它将重试重新连接设置的次数

但他是我的问题

    while 1:
        s.recv(1034)
当这失败时,我想尝试重新连接 我当然可以键入或只是再次复制连接部分,但我希望能够调用一个函数来处理连接,然后重试并将连接对象交还给我

比如像这样

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中是如何工作的,所以我认为我在这里遗漏了一些东西

仅供参考,以防您没有注意到iv对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()
            ...
类TCPClient():
def u u init _;(self、host、port、retryAttempts=10):
#这是接收主机和端口的构造函数。给出了重试尝试
#默认值,但也可以输入。
self.host=host
self.port=端口
self.retryAttempts=retryAttempts
self.socket=None
def连接(自身,尝试=0):
如果尝试推荐
对于这个用例,我建议使用比套接字更高级别的东西。为什么?当您只想检索或发送数据并维护连接时,为自己控制所有这些异常和错误可能会令人恼火

当然,你可以用简单的解决方案实现你想要的,但我认为你会把代码弄乱一点。无论如何,它看起来类似于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)
reconnect()
方法在某种程度上是您案例的核心——它在需要建立连接时被调用:当类初始化或连接中断时。
handle\u read()
操作任何接收到的数据,在这里您可以记录它或其他东西。 您甚至可以使用缓冲区(
self.out\u buffer+=“message”
)发送数据,在重新连接后,缓冲区将保持不变,所以类将在再次连接时恢复发送。 将
self.end
设置为
True
将通知班级尽可能退出


asyncore
在此类事件发生时处理异常和调用
handle\u close()
,这是处理连接故障的方便方法。

在上面的代码段中,什么是
self.connected
?@TomaszPlonka它是
asyncore.dispatcher
类的属性,表示套接字是否连接到某个端点。当执行
self.connect((self.host,self.port))
完成时,此属性将更新-如果出现错误
self.connected=False
,否则
True