Seite 1 von 1

Socket Connection Timeout

Verfasst: Donnerstag 5. Januar 2017, 13:45
von Majanao
Hallo zusammen,
ich bin schon eine Weile damit beschäftigt eine Netzwerkverbindung zwischen meinem Raspberry und meine PC aufzubauen.
Leider funktioniert das nicht so wie ich es will. Auf meinem Rechner starte ich den ThreadedServer und auf dem Pi den Client, der dann "Hallo Welt" senden soll.

Beide Geräte können sich gegenseitig anpingen aber, der Client stoppt bei sock.connect() schmeißt dann den timeout. Der Host wartet konstant auf eine Meldung des Clients bei sock.accept(). Das locale Netzwerk habe ich mit einem TPLinkWifi aufgebaut und den Port 1101 als Virtual Server geöffnet (auf jeden glaube ich das).

Habt ihr einen Tip für mich?

Code: Alles auswählen

import socket
import threading
from time import *


class ThreadedServer(object):
    def __init__(self, host=socket.gethostname(), port=1101):

        if host is None:
            self.host = socket.gethostname()
        else:
            self.host = host

        self.port = port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((self.host, self.port))

    def listen(self):
        self.sock.listen(5)
        while True:
            print("Waiting for client...")
            client, address = self.sock.accept()
            print ("Client %s gefunden mit der Adresse %s\n") % (client, adress)
            client.settimeout(60)
            threading.Thread(target=self.listenToClient, args=(client, address)).start()

    def listenToClient(self, client, address):

        print("Listener aktiviert fuer Server: %s\n") % socket.gethostname()

        size = 1024
        while True:
            try:
                data = client.recv(size)
                print(data)
                # if data:
                    # Todo: Daten handeln
                    # response = data
                    # client.send(response)

                # else:
                    # raise Exception('Client disconnected')
            except:
                client.close()
                return False


class Client(object):
    def __init__(self, host, port):

        self.host = host
        self.port = port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        print("Try to connect...")
        try:
            self.sock.connect((host, port))

        except socket.gaierror, e:
            print "Address-related error connecting to server: %s" % e
            sys.exit(1)
        except socket.error, e:
            print "Connection error: %s" % e
            sys.exit(1)
        print "Connected to %s" % host

    def connect(self, host, port):
        self.sock.connect((host, port))

    def send(self, data):
        totalsent = 0
        while totalsent < len(data):
            sent = self.sock.send(data[totalsent:])
            if sent == 0:
                raise RuntimeError("socket connection broken")
            totalsent = totalsent + sent


if __name__ == "__main__":

    modus = "host"

    if modus == "host":
        ThreadedServer().listen()

    elif modus == "client":
        c = Client('192.168.0.100', 1101)

        while True:
            c.send("Hello World!")
            print("Daten gesendet")
            sleep(1)

Re: Socket Connection Timeout

Verfasst: Donnerstag 5. Januar 2017, 14:52
von BlackJack
@Majanao: Funktioniert es denn wenn Client und Server auf dem gleichen Rechner laufen? Falls ja, ist es wahrscheinlicher dass das Problem an der Netzwerkkonfiguration liegt. Kannst Du Dich denn vom Raspi aus mit Telnet mit dem Server verbinden?

Re: Socket Connection Timeout

Verfasst: Donnerstag 5. Januar 2017, 15:59
von Majanao
Bingo,
wenn ich Host und Client auf dem Pi laufen habe, funktioniert es. Jetzt ist die Frage wieso es über den Wlan-Router nicht klappen mag.
Hast du eine Idee?

Re: Socket Connection Timeout

Verfasst: Donnerstag 5. Januar 2017, 16:14
von Majanao
Ok,
ich habe gerade nach deinem Tip noch etwas rumprobiert. Ich habe den Host nun auf den Pi gelegt und den Client auf meinen Rechner. Damit funktioniert es super.
Nur wieso läuft es nicht, wenn der Host auf dem PC läuft??

Vielen Dank für deine Hilfe!

Re: Socket Connection Timeout

Verfasst: Donnerstag 5. Januar 2017, 16:22
von Sirius3
@Majanao: Sternchenimporte sind schlecht. Wenn Du aus dem time-Modul nur sleep brauchst, dann importier das auch so »from time import sleep«. Nackte excepts (Zeile 44) solltest Du vermeiden. Das Fängt wirklich jeden Fehler, auch Programmierfehler (z.B. NameError) ab, und so wird es quasi unmöglich Fehlerquellen zu finden. Was für eine Exception möchtest Du denn an der Stelle verarbeiten? Bei einem Socket ohne »bind« braucht man SO_REUSEADDR nie (Zeile 55). Zeile 62/65: exit sollte nie außerhalb einer Hauptroutine aus aufgerufen werden, weil so wie jetzt »Client« nicht sinnvoll benutzt werden kann. Zeile 68: connect ist überflüssig, weil das schon in __init__ gemacht wird. Zeile 71ff: das was Du da mühsam selbst programmiert hast gibt es schon: socket.sendall.

Zum Problem: Du bindest den Server-Socket nur an den lokalen Host, d.h. Verbindungen von außerhalb werden geblockt. Das ist wahrscheinlich nicht, das was Du willst. Nimm als Host "0.0.0.0" um zu signalisieren, dass an jedem beliebige Gateway auf ankommende Verbindungen gewartet wird.

Re: Socket Connection Timeout

Verfasst: Dienstag 10. Januar 2017, 11:36
von Majanao
@Sirius3:
Vielen Dank für deine Anmerkungen. Du hattest Recht, da waren so einige Schnitzer im Code.

Die WLAN-Kommunikation funktionert jetzt, so lange der Host auf dem Pi läuft und der Client (PC) dem Host Daten (sendall) sendet. Jedoch muss für mein Projekt der Pi (Host) dem PC (Client) Daten schicken. Und genau das funktioniert nicht. Das Binden ist kein Problem, aber mein Skript hängt immer an client.recv(). Außerdem gibt es auf dem Host kein sendall.

Ist das vielleicht normal, dass der Host nicht zum Senden vieler Daten gedacht ist?

Re: Socket Connection Timeout

Verfasst: Dienstag 10. Januar 2017, 11:43
von Sirius3
@Majanao: Was heißt, hängt am recv? Warum gibt es auf dem Host kein sendall? Und falls es normal wäre, dass man nicht viele Daten senden kann, hätte das Netflix vielleicht schon gemerkt.

Mit anderen Worten: Du machst etwas falsch, um das aber herauszufinden brauchen wir Deinen Code.