slacky Skrevet 19. mai 2011 Del Skrevet 19. mai 2011 Hei. Jeg er relativt ny på python. Så jeg trenger hjelp til et "enkelt" script, hvor jeg skal kunne "pinge" en enkelt side i en loop... Slik at jeg hele tiden får output av enkeltresultater, skal etterpå forsøke å lage en simpel graph med responstiden... Over et tidsrom av f.eks en time.. Trenger ikke at den pinger så fort den får tilbake pakken, men en pakke pr. sekund skal duge. (3600) pakker, i timen. Vet det finnes ferdig software for dette, men ønsker å lære mer python i denne retningen. Kommer også til å modifisere denne, slik at jeg kan ved hjelp av scriptet/programmet automatisk aktivere backupservere, om hovedserveren min ikke gir en respons, så det må altså kjøre en evig loop, intill jeg velger å stoppe scriptet/lukke programmet. Lenke til kommentar
etse Skrevet 19. mai 2011 Del Skrevet 19. mai 2011 (endret) Python har ikke direkte støtte for å kunne pinge adresser gjennom sockets. Til dette er andre programmeringsspråk som f.ek.s C/C++/C# å anbefale. Men det finnes en vei man kan pinge via python med, men det blir ikke direkte fint - og heller ikke platformuavhengig. Faktisk vil implementasjonen og kun virke om han som kjører programmet kjører samme språk av operativsystemet som deg og. Måten jeg tenker på er å kjøre ping-applikasjonen som følger med OSet i en subprocess og bare lese resultatet fra pingingen; hvor man gjerne bare filtrere ut de faktiske tallene man er ute etter. import subprocess host = "www.google.com" ping = subprocess.Popen( ["ping", "-n", "4", host], stdout = subprocess.PIPE, stderr = subprocess.PIPE, ) out, error = ping.communicate() print out http://stackoverflow.com/questions/316866/ping-a-site-in-python En annen, mer platformuavhengig løsning ville vært: 1: Lage programmet i et annet språk med direkte støtte for å sende ping-pakker. 2: Lage en server og et klient script som du kjører og bare sender data over sockets. Server: - Lytte på en bestemt port - Akkeseptere alle tilkoblinger og tildele de en egen "worker" - Om den mottar "PING XXXX" (hvor XXXX er enten et random tall eller navnet på klienten) så skal den svare "PONG XXXX" tilbake til klienten. Klienten: - Koble til server på gitt IP og PORT - Sende PING med bestemt tidsintervall til server - Hvis ikke ping er svart på innen rimelig tid utfør bestemt oppgave. For å få til dette må du lese deg litt opp på sockets. Finnes masse god dokumenstasjon om det der ute Endret 19. mai 2011 av etse Lenke til kommentar
slacky Skrevet 19. mai 2011 Forfatter Del Skrevet 19. mai 2011 (endret) Hehe, satt å googlet masse selv, kom over den du linker til.. Selv om jeg ikke er fornøyd med en slik løsning, så fungerer det med subprocess.. Edit: #!/usr/bin/python # -*- coding: utf-8 -*- import subprocess import sys import re import time host = "www.NIX.no" cmd = "ping "+host+" -n 1" while 1: ping = subprocess.Popen( cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE, ) out, error = ping.communicate() regex = re.compile("Average = (\d+)ms") result = regex.findall(out) print ">>> Ping from: %s" % host for ping in result: print ">>> %s" % ping time.sleep(2) Planen er å lage en loop, som simpelthen kjører "ping "+host+" -n 1"; benytte meg av regex, for å hente "average = 15ms", spytte ut/printe resultatet, vent 1 sek, og kjør dette om igjen. Skal ikke være vanskelige en som så. Da var jeg godt på vei ) Nå må jeg lage en loop for å kjøre denne flere ganger Endret 19. mai 2011 av tROOP4H Lenke til kommentar
slacky Skrevet 19. mai 2011 Forfatter Del Skrevet 19. mai 2011 (endret) Scriptet er kommet langt... Fremdeles en bug jeg skal fjerne, og masse aplikasjoner som må legge til, benyttet meg av noe ferdig software for å lage grafen ... Har bare testet det på windows xp, husker ikke om win7, og win vista har samme oppsett i kommandolinjen. Krever følgende ekstrapakker: -wxPython -Numpy -matplotlib Edit..: Lagres som xxxx.pyw Scriptet: #!/usr/bin/python # -*- coding: utf-8 -*- import os import pprint import sys import wx import subprocess import re import matplotlib matplotlib.use('WXAgg') from matplotlib.figure import Figure from matplotlib.backends.backend_wxagg import \ FigureCanvasWxAgg as FigCanvas, \ NavigationToolbar2WxAgg as NavigationToolbar import numpy as np import pylab host = "www.NIX.no" cmd = "ping "+host+" -n 1" hz = 1000 class DataGen(object): def __init__(self, init=0): self.data = self.init = init def next(self): self._recalc_data() return self.data def _recalc_data(self): ping = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, error = ping.communicate() regex = re.compile("Average = (\d+)ms") result = regex.findall(out) for ping in result: delta = int(ping) self.data = delta class BoundControlBox(wx.Panel): """ A static box with a couple of radio buttons and a text box. Allows to switch between an automatic mode and a manual mode with an associated value. """ def __init__(self, parent, ID, label, initval): wx.Panel.__init__(self, parent, ID) self.value = initval box = wx.StaticBox(self, -1, label) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) self.radio_auto = wx.RadioButton(self, -1, label="Auto", style=wx.RB_GROUP) self.radio_manual = wx.RadioButton(self, -1, label="Manual") self.manual_text = wx.TextCtrl(self, -1, size=(35,-1), value=str(initval), style=wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_UPDATE_UI, self.on_update_manual_text, self.manual_text) self.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter, self.manual_text) manual_box = wx.BoxSizer(wx.HORIZONTAL) manual_box.Add(self.radio_manual, flag=wx.ALIGN_CENTER_VERTICAL) manual_box.Add(self.manual_text, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.radio_auto, 0, wx.ALL, 10) sizer.Add(manual_box, 0, wx.ALL, 10) self.SetSizer(sizer) sizer.Fit(self) def on_update_manual_text(self, event): self.manual_text.Enable(self.radio_manual.GetValue()) def on_text_enter(self, event): self.value = self.manual_text.GetValue() def is_auto(self): return self.radio_auto.GetValue() def manual_value(self): return self.value class GraphFrame(wx.Frame): """ The main frame of the application """ title = 'Netgraph Beta 0.1' def __init__(self): wx.Frame.__init__(self, None, -1, self.title) self.datagen = DataGen() self.data = [self.datagen.next()] self.paused = False self.create_menu() self.create_status_bar() self.create_main_panel() self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.redraw_timer.Start(hz) def create_menu(self): self.menubar = wx.MenuBar() menu_file = wx.Menu() m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file") self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt) menu_file.AppendSeparator() m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit") self.Bind(wx.EVT_MENU, self.on_exit, m_exit) self.menubar.Append(menu_file, "&File") self.SetMenuBar(self.menubar) def create_main_panel(self): self.panel = wx.Panel(self) self.init_plot() self.canvas = FigCanvas(self.panel, -1, self.fig) self.xmin_control = BoundControlBox(self.panel, -1, "X min", 0) self.xmax_control = BoundControlBox(self.panel, -1, "X max", 50) self.ymin_control = BoundControlBox(self.panel, -1, "Y min", 0) self.ymax_control = BoundControlBox(self.panel, -1, "Y max", 100) self.pause_button = wx.Button(self.panel, -1, "Pause") self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button) self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button, self.pause_button) self.cb_grid = wx.CheckBox(self.panel, -1, "Show Grid", style=wx.ALIGN_RIGHT) self.Bind(wx.EVT_CHECKBOX, self.on_cb_grid, self.cb_grid) self.cb_grid.SetValue(True) self.cb_xlab = wx.CheckBox(self.panel, -1, "Show X labels", style=wx.ALIGN_RIGHT) self.Bind(wx.EVT_CHECKBOX, self.on_cb_xlab, self.cb_xlab) self.cb_xlab.SetValue(True) self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) self.hbox1.Add(self.pause_button, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(20) self.hbox1.Add(self.cb_grid, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(10) self.hbox1.Add(self.cb_xlab, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) self.hbox2.Add(self.xmin_control, border=5, flag=wx.ALL) self.hbox2.Add(self.xmax_control, border=5, flag=wx.ALL) self.hbox2.AddSpacer(24) self.hbox2.Add(self.ymin_control, border=5, flag=wx.ALL) self.hbox2.Add(self.ymax_control, border=5, flag=wx.ALL) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW) self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.vbox.Add(self.hbox2, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.panel.SetSizer(self.vbox) self.vbox.Fit(self) def create_status_bar(self): self.statusbar = self.CreateStatusBar() def init_plot(self): self.dpi = 100 self.fig = Figure((3.0, 3.0), dpi=self.dpi) self.axes = self.fig.add_subplot(111) self.axes.set_axis_bgcolor('black') self.axes.set_title('Ping host: '+host+'', size=12) pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) # plot the data as a line series, and save the reference # to the plotted line series # self.plot_data = self.axes.plot( self.data, linewidth=1, color=(1, 1, 0), )[0] def draw_plot(self): """ Redraws the plot """ # when xmin is on auto, it "follows" xmax to produce a # sliding window effect. therefore, xmin is assigned after # xmax. # if self.xmax_control.is_auto(): xmax = len(self.data) if len(self.data) > 200 else 200 else: xmax = int(self.xmax_control.manual_value()) if self.xmin_control.is_auto(): xmin = xmax - 200 else: xmin = int(self.xmin_control.manual_value()) # for ymin and ymax, find the minimal and maximal values # in the data set and add a mininal margin. # # note that it's easy to change this scheme to the # minimal/maximal value in the current display, and not # the whole data set. # if self.ymin_control.is_auto(): ymin = round(min(self.data), 0) - 1 else: ymin = int(self.ymin_control.manual_value()) if self.ymax_control.is_auto(): ymax = round(max(self.data), 0) + 1 else: ymax = int(self.ymax_control.manual_value()) self.axes.set_xbound(lower=xmin, upper=xmax) self.axes.set_ybound(lower=ymin, upper=ymax) # anecdote: axes.grid assumes b=True if any other flag is # given even if b is set to False. # so just passing the flag into the first statement won't # work. # if self.cb_grid.IsChecked(): self.axes.grid(True, color='gray') else: self.axes.grid(False) # Using setp here is convenient, because get_xticklabels # returns a list over which one needs to explicitly # iterate, and setp already handles this. # pylab.setp(self.axes.get_xticklabels(), visible=self.cb_xlab.IsChecked()) self.plot_data.set_xdata(np.arange(len(self.data))) self.plot_data.set_ydata(np.array(self.data)) self.canvas.draw() def on_pause_button(self, event): self.paused = not self.paused def on_update_pause_button(self, event): label = "Resume" if self.paused else "Pause" self.pause_button.SetLabel(label) def on_cb_grid(self, event): self.draw_plot() def on_cb_xlab(self, event): self.draw_plot() def on_save_plot(self, event): file_choices = "PNG (*.png)|*.png" dlg = wx.FileDialog( self, message="Save plot as...", defaultDir=os.getcwd(), defaultFile="plot.png", wildcard=file_choices, style=wx.SAVE) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.canvas.print_figure(path, dpi=self.dpi) self.flash_status_message("Saved to %s" % path) def on_redraw_timer(self, event): # if paused do not add data, but still redraw the plot # (to respond to scale modifications, grid change, etc.) # if not self.paused: self.data.append(self.datagen.next()) self.draw_plot() def on_exit(self, event): self.Destroy() def flash_status_message(self, msg, flash_len_ms=1500): self.statusbar.SetStatusText(msg) self.timeroff = wx.Timer(self) self.Bind( wx.EVT_TIMER, self.on_flash_status_off, self.timeroff) self.timeroff.Start(flash_len_ms, oneShot=True) def on_flash_status_off(self, event): self.statusbar.SetStatusText('') if __name__ == '__main__': app = wx.PySimpleApp() app.frame = GraphFrame() app.frame.Show() app.MainLoop() Endret 20. mai 2011 av tROOP4H Lenke til kommentar
etse Skrevet 20. mai 2011 Del Skrevet 20. mai 2011 Tror de fleste er enige med meg når jeg sier så lange script burde legges ut på pastebin i stede for code-tags; slik at det blir lettere å lese. Så for de som vil lese gjennom den, her: http://pastebin.com/RvXeduE3 Lenke til kommentar
Terrasque Skrevet 20. mai 2011 Del Skrevet 20. mai 2011 (endret) http://mail.python.org/pipermail/tutor/2009-November/072706.html En som har laget ping i python via icmp raw sockets Edit : also, http://www.g-loaded.eu/2009/10/30/python-ping/ Endret 20. mai 2011 av Terrasque Lenke til kommentar
slacky Skrevet 20. mai 2011 Forfatter Del Skrevet 20. mai 2011 (endret) http://mail.python.org/pipermail/tutor/2009-November/072706.html En som har laget ping i python via icmp raw sockets Edit : also, http://www.g-loaded.eu/2009/10/30/python-ping/ Joda, har test dem... De viser dårlige resultater ved lav responstid. Pinget en side via kommandloninja hvor jeg hadde stabilt 7ms... Så testet jeg med de scriptene. Det resulterte i 0.0ms, 15ms, 0.0ms, 15ms... etc.. Så det var dårlig! Testet mot flere hoster, det viste bare korrekt mot sider som jeg hadde 35+ms til. Tror de fleste er enige med meg når jeg sier så lange script burde legges ut på pastebin i stede for code-tags; slik at det blir lettere å lese. Så for de som vil lese gjennom den, her: http://pastebin.com/RvXeduE3 Den er ikke oppdatert etter siste edit jeg gjorde, som fikset en del bugs... Men er en kjapp fiks for de med litt kunskap! Ellers får du ha takk for den Endret 20. mai 2011 av tROOP4H Lenke til kommentar
MailMan13 Skrevet 20. mai 2011 Del Skrevet 20. mai 2011 (endret) Så testet jeg med de scriptene. Det resulterte i 0.0ms, 15ms, 0.0ms, 15ms... etc.. Så det var dårlig! Testet mot flere hoster, det viste bare korrekt mot sider som jeg hadde 35+ms til. Du kan ikkemodifisere skriptet til å bruke en bedre klokke da? En som teller CPU-tid i stedet for å bruke systemklokke elns... Vanlig systemklokke i en pc har rundt 15-16ms oppløsning, så 0-15-0-15... resultatet er ikke så veldig rart hvis det er den som brukes. Endret 20. mai 2011 av MailMan13 Lenke til kommentar
slacky Skrevet 20. mai 2011 Forfatter Del Skrevet 20. mai 2011 (endret) Så testet jeg med de scriptene. Det resulterte i 0.0ms, 15ms, 0.0ms, 15ms... etc.. Så det var dårlig! Testet mot flere hoster, det viste bare korrekt mot sider som jeg hadde 35+ms til. Du kan ikke modifisere skriptet til å bruke en bedre klokke da? En som teller CPU-tid i stedet for å bruke systemklokke elns... Vanlig systemklokke i en pc har rundt 15-16ms oppfriskning, så 0-15-0-15... resultatet er ikke så veldig rart hvis det er den som brukes. Joda, det finnes noen alternativer, nå som jeg vet hvorfor. Jeg tør å påstå at en kan benytte: time.clock(), som henter tiden på den måten du spessifiserer. Men, den er "treg" å kalle. Hvor den da bruker opp til 2ms, så det må vel trekkes fra ~2ms på output.. dette må jeg bare se ann, og teste. Disse scriptene som ble vist til, vil fungere bedre på linux-systemer, hvor oppfriskningene pr. sekund er høyere. Det er ikke feil i selve python-pakken. Endret 20. mai 2011 av tROOP4H Lenke til kommentar
snippsat Skrevet 20. mai 2011 Del Skrevet 20. mai 2011 (endret) En alternativ løsning hvor man ikke bruker subprocess,bruker timeit og Httplib2 Som vist her. http://fitzgeraldsteele.wordpress.com/2009/01/15/simple-web-response-time-testing-with-python/ Jeg lagde en test med matplotlib for gøy. import timeit import time import matplotlib.pyplot as plot # Request the page 20 times, time the response time t = timeit.Timer("h.request('http://www.google.no/',headers={'cache-control':'no-cache'})", "from httplib2 import Http; h=Http()") ping_list = t.repeat(20,1) ping = [] for item in ping_list: ping.append(item) plot.xlabel('Seconds') plot.ylabel('Ping') plot.title('Ping Over Time') #Set the axis, and the horizontal tick marks plot.axis([1, 2, 0, 1]) plot.xticks(range(1, 20)) #actually do the plotting # The [None], along with the setup let you not have 0 seconds plot.plot([None] + ping) plot.show() Synes dette var en artig bruk av timeit som jeg har brukt mye. Kan ta litt om timeit og den mere vanlige bruken av den. Hvilken kode/algoritme er rasket? Dette er spørsmålet man stiller seg mange ganger,koden under er for rask til og kjøre en gang. #ordinary loop l = [] for i in xrange(10): l.append(i*2) print l #Python list comprehension l = [i*2 for i in xrange(10)] prin l Her kommer timeit inn i bildet. Vi kjører koden 10000000 ganger og timeit gir ut en gjennomsnitt tid. import timeit ol = ''' l = [] for i in xrange(10): l.append(i*2) ''' lc = ''' l = [i*2 for i in xrange(10)] ''' print timeit.Timer(stmt=ol).timeit(number=10000000) #ol(ordinary loop) time was 12.1718016571 #lc(list comprehension) time was 7.78384060041 Så list comprehension er litt raskere enn en vanlig loop. Endret 20. mai 2011 av SNIPPSAT Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå