2013-03-01 29 views
3

我尝试守护一些代码,但我遇到了一些麻烦。使用python-daemon守护python脚本 - socket trouble

如果我用tklogger()调用代码,它运行得很好。但是,如果我把它在后台方面,我得到了以下跟踪:

Traceback (most recent call last): 
    File "./tklogger.py", line 103, in <module> 
    tklogger() 
    File "./tklogger.py", line 41, in tklogger 
    conn, addr = s.accept() 
    File "/usr/lib/python2.6/socket.py", line 195, in accept 
    sock, addr = self._sock.accept() 
socket.error: [Errno 9] Bad file descriptor 
close failed in file object destructor: 
IOError: [Errno 9] Bad file descriptor 

我的代码如下:

#!/usr/bin/python 

# tklogger, a TK10X GPS tracking device logger 

import socket 
import time 
import daemon 

HOST = ''      # Bind to all interfaces 
PORT = 9000      # Arbitrary non-privileged port 
IMEI = '359710040656622'  # Device IMEI 
REQUEST_DATA = 1    # Do we want to request data? 
INTERVAL = 30     # How often do we want updates? 
LOGDIR = '/var/log/tklogger/' # Where shall we log? 

# END CONFIG 

# Establish socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # allow re-use of the address 
s.bind((HOST, PORT)) 
s.listen(1) 

# Open log files 
logger = open(LOGDIR + 'tklogger.log', 'a') 
deviceLog = open(LOGDIR + IMEI + '.csv', 'a') 

def sendTracker(DATA): 
    conn.send(DATA) 
    log("\t<< " + DATA) 

def log(DATA): 
    #print (DATA) 
    logger.write(DATA + '\n') 
    logger.flush() 

def tklogger(): 
    # Accept connections as they come 
    while 1: 
     global conn 
     conn, addr = s.accept() 
     strNow = time.strftime("(%d/%m/%Y %H:%M:%S)", time.localtime(time.time())) 
     log(strNow + ' Accepted connection from ' + addr[0]) 

     # Fetch data from the socket 
     while 1: 
      data = conn.recv(1024) 
      if not data: break 
      data = data.rstrip() 
      log("\t>> " + data) 

      # Check for logon & send data request 
      if data == '##,imei:' + IMEI + ',A;': 
       sendTracker('LOAD') 
       if REQUEST_DATA: 
        time.sleep(5) 
        request = '**,imei:' + IMEI + ',C,' + str(INTERVAL) + 's' 
        sendTracker(request) 

      # Check for heartbeat 
      if data == IMEI + ';': 
       sendTracker('ON') 

      # Parse actual data 
      if data[:20] == 'imei:' + IMEI: 

       # Split into fields 
       # id, mode, dateTime, ??, LBS??, ??, fixType??, lat, N/S, lon, E/W, speed?, bearing? 
       fields = data.split(','); 
       if fields[6] == 'A': 

        # Hopefully we have the protocol right... 
        try: 
         # Convert to degress decimal. 
         latDeg = round(float(fields[7][:2]) + (float(fields[7][2:])/60.0), 5) 
         lonDeg = round(float(fields[9][:3]) + (float(fields[9][3:])/60.0), 5) 
         if fields[8] == 'S': latDeg = -latDeg 
         if fields[10] == 'W': lonDeg = -lonDeg 

         # Date & time 
         msgDate = fields[2][4:6] + '/' + fields[2][2:4] + '/' + fields[2][:2] 
         msgTime = fields[2][6:8] + ':' + fields[2][8:] 

         # Speed 
         speed = round(1.852 * float(fields[11]), 2) 

         # Bearing 
         bearing = float(fields[12].rstrip(';')) 

         # Log the device data 
         deviceLog.write(msgDate + ',' + msgTime + ',' + str(latDeg) + ',' + str(lonDeg) + ',' + str(speed) + ',' + str(bearing) + '\n') 
         deviceLog.flush() 

        # Just in case something goes wrong though 
        except: pass 

     conn.close() 
     strNow = time.strftime("(%d/%m/%Y %H:%M:%S)", time.localtime(time.time())) 
     log(strNow + ' Connection from ' + addr[0] + ' closed') 


with daemon.DaemonContext(stderr = logger): 
    tklogger() 

建议,将不胜感激!

+3

最简单的解决方法是避免在守护进程之前打开文件,套接字。 – jfs 2013-03-01 05:56:47

+0

谢谢,这是排序:-) – Terry 2013-03-01 06:08:01

回答

8

守护进程的行为会杀死所有现有的套接字。因此,在守护进程之后(在DaemonContext中),您必须打开您的套接字s