Klient, który powinien uruchomić serwer gdy ten nie działa, zawiesza się

0

Dzień dobry.

Mam, po wielu trudach serwer, który się włącza nawet wtedy, gdy wcześniej został zamknięty przez CRTL+Z (Linux). Klient powinien go uruchomić, jeżeli stwierdzi, że nie działa.

Niestety, tak się nie dzieje. Proszę o wskazówkę gdzie może być problem. Klient nawet nie printuje gdy kod printów jest na samej górze kodu. Nie wiem czemu, bo jak serwer działa, to wszystkie printy testowe działają.

Załączam kod:

#!/usr/bin/python3

#KLIENT

import socket
import sys
import os
import time

print("000", end="")

HOST = ''       # The remote host
PORT = 50007    # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("a", end="")
while 1:
    try:
        s.connect((HOST, PORT))
        print("!", end="")
        break
    except Exception as e:
        os.fork()
        os.system("nohup python3 ./serv.py")
        time.sleep(2)
param = ""
if 1 < len(sys.argv):
    param = str(sys.argv[1])
s.send(param.encode())
data = s.recv(1024).decode()
s.close()
print(data, end='')
#!/usr/bin/python3
# SERWER

import sys
import socket
import subprocess
import re
import os, signal
import time

HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while 1:
    try:
        s.bind((HOST, PORT))
        break
    except Exception as e:
        p = subprocess.Popen("lsof -w | grep serv.py | grep IPv4 | grep LISTEN | awk '{print $2}'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        output, error = p.communicate()
        pid = int(re.sub("\n", "", output.decode()))
        os.kill(pid, signal.SIGKILL)
        time.sleep(1)
s.listen(1)
while 1:
    conn, addr = s.accept()
    data = conn.recv(1024).decode()
    if not data:
        conn.close()
        break
    try:
        conn.send((data + "moje dodatki").encode())
    except Exception as e:
        conn.send(str(e).replace("\n", " ").encode())
    conn.close()

Dzięki
M.

0

Mam, po wielu trudach serwer, który się włącza nawet wtedy, gdy wcześniej został zamknięty przez CRTL+Z (Linux).

Już Ci ktoś napisał, ale dalej uparcie twierdzisz swoje, CRTL+Z nie zamyka procesów. On je usypia.

0

@szatkus: Dziękuję, wersja na Django działa. Jednak jeżeli ktoś z Was umiałby pomóc w wersji na sockecie to proszę o pomoc. Dzięki!

1

Systemd by rozwiązał problem. Do tego służy. Tworzysz 2 unity, jedne wymagany przez drugi. W ten sposób masz kod niezależny od platformy, a na poziomie platformy zdefiniowane zależności potrzebne to wystartowania serwisów.

Co do samego printa, "000" utknęło w buforze po stronie jądra. Jakbyś zrobił flush to by wypisało (print("000", end="", flush=True)).

0

Dziękuję. Właśnie czytam o tym systemd. Spróbuję to ogarnąć. Meanwhile czy mógłbyś sypnąć jakimś przydatnym linkiem, bo to co znalazłem średnio rozumiem ;P

0

I ten fork to po co, skoro wołasz os.system("nohup python3 ./serv.py")

2

Przede wszystkim to należy go (fork) poprawnie używać. Fork tworzy kopię obecnego procesu. Zwraca wartość, która służy do identyfikacji czy jest się w kopi procesu, czy w oryginalnym procesie. https://docs.python.org/3/library/os.html#os.fork

Wołanie fork w pętli, tak jak w tym kodzie, skutkuje tworzeniem kopii procesów w nieskończoność.

0

No dobra, a jak sprawdzić, czy dany proces serwera, jest uśpiony czy jest nowym procesem?

0

jest we mnie coś głębokiego na "nie" do takiej architektury - pisałem w poprzedni poście @mpaw n/t

A teraz dociera do mnie, że jeszcze django do tego. Żaden serwer / framework webowy nie lubi się z obcymi procesami.
Toż to zamotanie jak twory @zku...i w C/C++

Po cholerę w ogóle te forki i procesy? Nie widzę tu ŻADNEGO uzasadnienia.
Potem autor dzielnie rozwiązuje problemy nieznane innym.

Python jest tak skutecznym językiem, że da się wsztsko napisać in-place i to zwięzłe

0

Chyba już doszedłem czemu nie działa ten kod. Po prostu, zabijać można tylko procesy spokrewnione. Jak uruchamiam serwer ręcznie i go zawieszam, to nie mogę go zabić innym procesem. Mogę to zrobić tylko z konsoli. Tylko teraz nie wiem, jak to obejść. Proszę o wskazówki jak to ominąć, dzięki.

M.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0