Ongelmia UDP listener threadin kanssa (Python 2.7)

Anonyymi

Olen koodaamassa qRadarille plugaria erästä systeemiä varten. Koodi on tarkoitus tehdä Pythonilla (versio 2.7) ja REST-toteutukseen käytetään Flask-kirjastoa. Olen koodannut luokan, jonka yhtenä osana on erityinen listener-threadi (jonka erillinen manager-thread käynnistää). Toteutus käyttää pythonin socketia, mutta jostain syystä bindaus feilaa. Koodin alkuosa (jossa alustetaan ja bindataan socket) on seuraavanlainen:

try:
# Set timeout for socket to prevent thread from getting stuck on termination
self.listener_error = "Setting socket timeout failed"
socket.setdefaulttimeout(2)
# Initiate socket
self.listener_error = "Instantiating socket failed"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Enable address reuse
self.listener_error = "Enabling adress reuse failed"
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Bind the socket to given address
self.listener_error = "Binding socket failed"
s.bind((self.ip_address, int(self.port)))
self.is_listening = True
self.is_connected = True

Muuttujaa listener_error käytetään tarkemman virheviestin välittämiseen kutsujalle. Kutsuttaessa tulee virhe "binding socket failed", joten jostain syystä bindaus ei toimi. Missä voisi olla vika ? ip_address ja port asetetaan ylemmällä tasolla ja asetusfunktiossa tarkistetaan niiden kelvollisuus, joten siitä ei pitäisi olla kyse. Voin toki varmuuden vuoksi lisätä ne virheilmoitukseen.

Koodissa muuttujaa is_listening käytetään managerissa tarkistamaan onko listener käynnissä (en tunne Pythonia niin hyvin, enkä äkkiseltään keksinyt parempaa tapaa) ja is_connectedia tarkastellaan ylemmän tason funktiossa, jotta selviäisi onnistuiko kytkentä tietyn ajan sisällä.

6

259

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Anonyymi

      Tuohan on erinomainen.

      T. Urpo

    • Anonyymi

      Ei ole kovin helppoa jäljittää virheen syytä kun ainoa tieto on, että virhe tulee nimen omaan bindissa (seuraavana vaiheena on varsinainen vastaanottosilmukka ja sitä ennen virheilmoitukseksi vaihdetaan "internal operation error", mutta siihen asti ei selvästikään päästä). Olisiko mahdollista esimerkiksi except-lohkossa hakea tarkempi virheviesti ja lisätä se perusvirheeseen ja jos on, miten ?

    • Anonyymi

      Sellainen lisäys vielä, että lisäsin except lohkoon määrittelyn "...socket.error as msg" ja except-lohkon alle rivin

      self.listener_error = self.listener_error ": " msg

      Tuon pitäisi antaa vielä tarkempi virhekuvaus, mutta jostain syystä mitään ei tule. Edes kaksoispistettä ei tule. Ikään kuin tuossa ei tulisikaan exceptionia vaan listener-thread jäisi jotenkin jumiin tuohon bindiin ja ylemmän tason funktiossa tulee timeout (odotetaan silmukassa 100 kertaa 0.1 sekunnin delayn kanssa, siis yhteensä 10 sekuntia). En tiedä onko tuollainen odotus oikea tapa, mutta en keksi parempaakaan.

      Listenerin aktivointi toimii siis siten, että ylemmän tason funktio kutsuu listener-luokan (johon manageri ja listener-funktio kuuluvat) funktiota, joka asettaa IP-osoitteen ja portin. Funktio tarkistaa, että arvot ovat kelvolliset ja jos ne ovat asettaa ne muuttujiin "uusi IP-osoite" ja "uusi portti". Manager-threadi (joka siis pyörii taustalla jatkuvasti omana threadinaan) huomaa, että IP-osoite tai portti on muuttunut ja instantioi listener-threadin. Jos kaikki menee oikein listener-thread tekee alustukset ja asettaa sitten tuon is_connected-lipun. Samalla se funktio, joka asetti alun perin arvot on odottamassa silmukassa. Jos se huomaa is_connected-lipun asettuneen (se nollattiin alussa) ennen ajan loppumista se palauttaa "OK" statuksen, muuten virheen.

      Testasin myös soketin alustamista suoraan palvelimella Pythonin interaktiivisessa tilassa. Siis:

      # python
      >>> import socket
      >>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      >>> socket.setdefaulttimeout(2)
      >>> s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      >>> s.bind(("xxx.xxx.xxx.xxx", 4740))
      >>> data = s.recvfrom(1000)
      >>> print data
      >>> "bla bla bla"

      Eli interaktiivisessa moodissa toimi ilman ongelmia. IP-osoite oli sama kuin softalle välitetty. Alkaa vaikuttaa aika mysteeriseltä.

      Voisiko olla, että tuo int() portin numeron määrittelyssä on jotenkin väärin tai bind ei jotenkin tykkää siitä ? Molemmat parametrit (IP-osoite ja portti) välitetään funktiolle normaalin HTML-formin kautta input-kentistä POST-metodin välityksellä (ja näyttäisivät kyllä olevan oiken virheilmoitukseen lisäämäni tulostuksen perusteella).

      • Anonyymi

        Ota try hetkeksi pois, niin jysähtää kunnolla ja saat pythonin error viestin.

        Laita väliprinttejä ja tarkista muuttujien, kuten ip osoitteen ja portin arvot, että ovat järkevät. Tai vaihtoehtoisesti aja koodi rivi kerrallaan debuggerilla.


      • Anonyymi

        Niin ja toki voi olla.

        type() funktiolla voit tarkistaa, mitä tyyppiä muuttujasi ovat.


    • Anonyymi

      Itse asiassa vaikuttaa siltä, että tässä tapauksessa qRadar blokkaa bindauksen (luultavasti turvalisuussyistä). Muutin except-rivin muotoon

      except socket.error as msg:

      ja lisäsin except-lohkon alle rivin

      self.socket_error = self.socket_eror ": " msg

      Jolloin exceptin antama virheviesti pitäisi olla mukana virhetekstissä (virheteksti tulee näkyviin ja se osoittaa, että ongelma on nimen omaan bindissa), mutta sitä ei näy. Virhesivulla näkyy ainoastaan perusvirhe ("bind failed"), ei kaksoispistettä tai lisätekstiä.

      Teoriani on, että qRadar blokkaa turvallisuussyistä omien sovellusten bindausyritykset, mutta ei kuitenkaan aiheuta poikkeusta. Kun bindaus blokataan kutsuvassa koodissa tulee timeout ja listenerin aktivointi feilaa.

      Kenties qRadarin asetuksista löytyy keino sallia bindaus. Jos ei, niin täytyy keksiä jotain muuta, esmes aktivoida serverillä ulkoinen listener (luin jostain sovelluksesta joka voisi sopia, muistaakseni nimeltään socat) ja ohjata sen tulostus tiedostoon, josta haetaan tiedot...

    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Nainen kokki autossa kammottavan kuoleman sähköauto-Teslan syttyessä tuleen.

      https://www.is.fi/autot/art-2000011652873.html Näin vaarallisia sähköautopalot voivat olla.
      Maailman menoa
      84
      5157
    2. Persuja ei aluevaltuustoissa näy

      Ei tunnu persuja paljon paikalliset asiat kiinnostavan, vaan ainoastaan ulkomaalaiset, joku Israel ja Trumpin fanitus.
      Maailman menoa
      25
      3480
    3. Päivän Riikka: Uudenkaupungin autotehdas hiljeni

      Näin ne 100 000 uutta pysyvää ei-tempputyötä yksityiselle sektorille tämän hallituksen ansiosta syntyy. Työntekijöille j
      Maailman menoa
      38
      2828
    4. Riikka vie Suomen kohta ykköseksi työttömyyskisassa

      Espanja: 10,5 % Suomi: 10,3 % Ruotsi: 9,3 % Kisa on tiukkaa, mutta Riikalla hyvä draivi päällä. Vasemmistolaisen päämin
      Maailman menoa
      9
      1972
    5. Kerro kaivattusi nimi tai nimikirjaimet

      🌠 Tähdenlento! Kirjoittamalla kaivattusi nimen tai nimikirjaimet tähän, saattaa toiveesi toteutua.
      Ikävä
      58
      1820
    6. Miksi pitäisit enemmän

      Minusta kuin siitä toisesta?
      Ikävä
      47
      1586
    7. Alkuvuodesta poistuu työttömyyskorvaus kaikilta joilla on säästössä rahaa

      Tippuu korvaukselta iso määrä työttömiä.
      Maailman menoa
      263
      1476
    8. Mitä meidän välillä

      Tulee tapahtumaan vai tuleeko mitään?
      Ikävä
      94
      1382
    9. Tämmönen höpsö

      Höpönassu mä olen. En mikään erikoinen…hölötän välillä ihan levottomia. Tykkäisit varmasti jos olisin siellä sun vieress
      Suhteet
      44
      1356
    10. Hiljaisuus

      Tarkoittaa välinpitämättömyyttä, henkistä väkivaltaa ja kiusaamista. Olet valinnut hiljaisuuden.
      Ikävä
      73
      1078
    Aihe