server client nur über localhost und nicht über netzwerk

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
fanto
User
Beiträge: 13
Registriert: Samstag 29. Juni 2013, 13:58

Also ich hab folgendes problem das programm (in python 3)funktioniert nur wenn server client programme beide auf einen rechener laufen wenn ich das eine auf einen anderen rechener zieh geht es nicht mehr.

Server

Code: Alles auswählen

import socket
def connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', 50000))
    s.listen(1)
    komm, addr = s.accept()
    data = komm.recv(1024)
    print('[%s] %s' % (addr[0],(str(data))))
    komm.close()
    s.close()
def config():
    connect()

config()
    
Client

Code: Alles auswählen

import socket
def connect(ip):
    #ip = input('IP-Adresse: ')
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((ip, 50000))
    aut = 'hallo'
    aut = bytes(aut, "utf-8")
    s.send(aut)
    s.close()
def config():
    datei=open('config.txt','r')
    ip = datei.readline()
    datei.close()
    connect(ip)

config()
mfg fanto
BlackJack

@fanto: Was heisst denn „geht […] nicht mehr”? Gibt es Fehlermeldungen, falls ja welche? Tracebacks? Falls ja, bitte 1:1 zeigen.

Der Client kann in dieser Form niemals gelaufen sein, auch nicht auf dem gleichen Rechner. Oder übersehe ich gerade wo der Name `aut` definiert wird? Und sollte das vielleicht `out` heissen? Oder ist das eine Abkürzung? Wofür? Abkürzungen sollte man vermeiden, solange sie nicht allgemein bekannt sind. Das bremst den Leser nur unnötig beim lesen und verstehen des Programms aus.

Ein Kommentar ``# Imports`` vor den Importen ist sinnfrei. Dass da die Importe stehen sieht man doch schon am Code.

`connect()` erscheint mir zu spezifisch für das was die beiden Funktionen jeweils tun, denn das ist ja deutlich mehr als nur die Verbindung herzustellen — dort läuft das Hauptprogramm und die Verbindung wird auch wieder abgebaut. Im Original hiessen sie ja auch `main()`. Dort gibt es auch noch das ``if __name__ == '__main__':`` Idiom, was leider verloren gegangen ist.

Das Schliessen von `komm` (verbesserungswürdiger Name) könnte man auch in einem ``finally``-Block erledigen. Oder etwas moderner mit ``with`` und `contextlib.closing()`. Dann bei allen Socket-Objekten. Dateien sollte man auch mit ``with`` verwenden.

Warum geben die Funktionen eine 0 zurück? Das macht keinen Sinn.  Der Wert wird ja auch nirgends benutzt.

Diese Funktionskaskade mit `config()` und `connect()` ist eine ungünstige Aufteilung von Funktionsaufrufen. Eine Funktion sollte nur eine Sache erledigen, die auch gut zu ihrem Namen passt. Und von einer `config()`-Funktion erwartet man, dass sie etwas konfiguriert, aber nicht dass sie auch noch das Hauptprogramm anstösst. Hier gilt auch wieder das mit den Abkürzungen, also `configure()`, denn `config` ist eher ein Name für ein Datenobjekt welches die Konfigurationsdaten enthält. Faustregel: Funktions- und Methodennamen sollten nach Tätigkeiten benannt sein, und nicht nach Dingen, denn sie repräsentieren Tätigkeiten.

Die `config()` im Server ist zusätzlich noch überflüssig.

Zu guter Letzt: Das Programm ist fehlerhaft, weil es einfach davon ausgeht, dass bei einem `send()` tatsächlich alle Daten gesendet wurden, und bei einem `recv()` alle Daten empfangen wurden die zu *einer* Nachricht gehören. Beides Garantien, welche die Socket-API *nicht* gibt. Lies Dir dazu mal die Dokumentation zu den beiden Methoden durch. Beim Senden lässt sich das noch recht einfach durch `sendall()` beheben, aber beim Empfangen muss man entweder deutlich aufwändigeren Code schreiben, der mit allen Varianten die auftreten können klar kommt, oder man lässt sich von den Socket-Objekten ein Dateiobjekt geben und hat dann all die Garantien, die Dateiobjekt in Python bezüglich `read()` und `write()` bieten. Hier dann beim Schreiben `flush()` nicht vergessen, damit nicht eine Seite „hängen” bleibt, weil die Daten ewig in einem Pufferspeicher liegen bleiben.
fanto
User
Beiträge: 13
Registriert: Samstag 29. Juni 2013, 13:58

1 also über localhost als ip funktioniert es wunderbar auf dem zwei rechnern einer server einer client gibt es die unten stehende fehlermeldung
2 ich hab den quelltext bereits verändert (falschen eingefügt)
3 wenn ich die verbindung über w-lan nutze passiert garnichts (zu langsam oder ist es die frizbox weis was ich) über lan und internet ip gibt es jetzt folgende meldung: ...line 5, in s.connect((ip, port))
socket.gaierror: [Errno 11004] getaddrinfo failed


das ist der relevante teil der fehlermeldung
fanto
achso die config() im server ist dazu gedacht (später wenn es soweit läuft) damit man schnell ports usw ändern kann und für weitere verbindungseinstellungen
BlackJack

@fanto: Ich hatte ja einiges über `send()` und `recv()` gesagt, das solltest Du vielleicht erst mal ausbessern.

Kann es sein, das in der Datei mit der IP-Adresse ein Zeilenendezeichen hinter der IP steht? Das solltest Du entfernen (im/per Code, nicht in der Datei).
fanto
User
Beiträge: 13
Registriert: Samstag 29. Juni 2013, 13:58

hm ja das mit send unr recv ist mir (im moment) egal es geht auch nicht wenn ich im client programm s.connect(("xxx.xxx.xxx.xxx", 50000)) also daran kann es eigendlich nicht liegen
ach der error kommt nur beim client programm
BlackJack

@fanto: Kannst Du den Rechner mit dem Server vom Rechner mit dem Client aus anpingen?
fanto
User
Beiträge: 13
Registriert: Samstag 29. Juni 2013, 13:58

ja über die internet ip ja, lan ja, und über w-lan(direkt) teilweise
fanto
User
Beiträge: 13
Registriert: Samstag 29. Juni 2013, 13:58

hm jetzt geht es villeicht haben sich win 7 und xp nicht vertragen aber eigendlich kann es das doch nicht sein hm jetzt win 7 win 7 gehts
lösung: ein zeichen anhängen bei mir : und dann mit 'ip = ip[:-1]'
Antworten