Работа с доменными сокетами Unix в Python - PullRequest
0 голосов
/ 29 ноября 2018

По сути, я начал использовать сокеты, потому что они быстрые и эффективные.В основном у меня есть программа на 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 голосов
/ 29 ноября 2018

У вас есть несколько вариантов здесь.

Самое простое - просто взять существующую функцию 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)

Если отправитель сокета уже доставляет строки, завершенные символами новой строки,вы можете преобразовать сокет непосредственно в файл-подобный объекту python с makefile, как объясняет ответ Даниэля Придена.(Но стандартный файловый объект будет ожидать нахождения «строк» ​​и будет пытаться читать до тех пор, пока не найдет символ конца строки.)

Если он не предоставляет символы новой строки (какс помощью, скажем, стандартного отправителя системного журнала), вы можете создать свой собственный подкласс сокета, который обеспечивает аналогичное поведение с семантикой записи за один раз:

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)
...