在Python中使用Unix域套接字的方法-如何在来自套接字的行中循环并在这些行上执行操作?

时间:2018-11-29 15:38:57

标签: python sockets unix unix-socket tcpsocket

基本上,我开始使用套接字是因为它们的速度和效率。基本上,我在python中有一个程序可以解析来自套接字的行,但是该程序可以在.txt文件上工作。我试图找出一种方法来合并我的程序,但要在套接字上使用它。代码如下。

#!/bin/python

import socket
import os, os.path

if os.path.exists("/home/log/socket"):
  os.remove("/home/log/socket")

log = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
log.bind("/home/log/socket")

while True:
  print(log.recv(4096))

这就是我用来接收套接字的内容。我主要担心的是,在将数据从套接字获取之前,必须先解析它,然后再将其上传到数据库。

这是我的python解析程序。

import threading

def text_org():   #fuction, if you want to run this, make sure you call the fuction!
    threading.Timer(300.0, text_org).start()


    infile = open('/home/log/radius.log', 'r') #file to operate on
    outfile = open('current_logs_sql_ready.txt', 'w')       #ending file, change name here to change the final file name
    error_count = 0
    time_count = 0

    for l in infile:                           #loops through each line in the file
        tokens = l.split()                      #counter

        if len(tokens) >19:                     #checks to make sure each line in valid in the .log file
            outfile.write(l.split()[+0] +'-') #Gets Day
            outfile.write(l.split()[+1] +'-') #Gets Month
            outfile.write(l.split()[+3] + ',')  # Gets Year
            outfile.write(l.split()[+2] + ',')  # Gets Time
            outfile.write(l.split()[-2] + ',')  # Gets Device
            outfile.write(l.split() [+9] + ',')  # Gets ID
            outfile.write(l.split()[+18] + ',')  # Gets AP
            outfile.write(l.split()[+19] + ',')  # Gets AP Group
            outfile.write(l.split()[+16] + '\n')  # Gets MAC
            time_count +=1


        else:                                      #this happens when a line in the file is invalid
            #outfile.write(l.split()[] + 'ERROR \n')  # Gets MAC
            print("Invalid Line \n")
            error_count +=1


    #print(error_count)
    #print('times ran =') +(time_count)


    infile.close()
    outfile.close()

text_org()    #runs the program

基本上,我想将我的解析程序与套接字而不是.txt文件一起使用。谢谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您在这里有几种选择。

最简单的方法就是简单地使用现有的text_org函数并将“ parse-a-single-line”部分分解成一个单独的函数。重构后,您的代码将如下所示:

def parse_line(outfile, line):
    tokens = line.split()
    outfile.write(...)
    ...

def text_org():
    ...
    with open('/home/log/radius.log', 'r') as infile:
        with open('current_logs_sql_ready.txt', 'w') as outfile:
            for l in infile:
                parse_line(outfile, l)

然后,通过您的套接字处理程序:

log = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
log.bind("/home/log/socket")

with open('current_logs_sql_ready.txt', 'w') as outfile:
    while True:
        line = log.recv(4096).decode()
        parse_line(outfile, line)

,如果套接字发送者已经交付了以换行符结尾的行,则可以使用makefile将套接字直接转换为类似python文件的对象,如Daniel Pryden的回答所述。 (但是,标准文件对象将期望找到“行”,并且只要找不到行末字符就将继续尝试读取。)

如果它不提供换行符(例如,与标准syslog发送器一样),则可以创建自己的套接字子类,该子类提供一次记录迭代器语义的类似行为:

class mysock(socket.socket):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    def __iter__(self):
        return self
    def __next__(self):
        return self.recv(4096).decode()

log = mysock(socket.AF_UNIX, socket.SOCK_DGRAM)
log.bind("/home/log/socket")   

with open('current_logs_sql_ready.txt', 'w') as outfile:
    for line in log:
        parse_line(outfile, line)