Socket [WinError 10061]

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
ThePaulCraft
User
Beiträge: 11
Registriert: Samstag 10. Oktober 2020, 17:43

Hallo,
Ich habe mir gerade eben das Video sockets von Tech With Tim angesehen, ich habe die erste funktionierende Version von server und client nachprogrammiert und wollte diese jetzt ausprobieren. Mein Problem:
Wenn ich den Code ausführe, dann erscheint folgende Fehlermeldung: "ConnectionRefusedError: [WinError 10061] Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die Verbindung verweigerte" (Ich weiß leider nicht wie ich ein Feld erstelle :D )Ich habe leider keine Ahnung was Windows/Python mir damit sagen will.
Hier mein Code:
Server.py:
"import socket
import threading

HEADER = 64
PORT = 1337
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!DISCONNECT"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)

def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr}")

connection = True
while connection:
msg_lenght = conn.recv(HEADER).decode(FORMAT)
msg_lenght = int(msg_lenght)
msg = conn.recv(msg_lenght).decode(FORMAT)
print(f"[{addr}]{msg}")
if msg == DISCONNECT_MESSAGE:
connection = False
conn.close()


def start():
server.listen()
print(f"[LISTENING] server is listening on {SERVER}")

while True:
conn, addr = server.accept()
thread = threading.Thread(handle_client, args=(conn,addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")

print("[STARTING] server is starting...")
try:
start
except:
pass
print("[STARTING] server started sucessfully!")"
Client.py:
"import socket

HEADER = 64
PORT = 1337
SERVER = "192.168.0.164"
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!DISCONNECT"
ADDR = (SERVER,PORT)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)"

Ich würde mich über eine Antwort sehr freuen!
mfg!
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

„Funktionierend” ist eine weit gefasste Definition. Es ist zwar ein bißchen besser als 99.999% aller Beispiele über Socket-Programmierung im Netz, aber immer noch fehlerhaft.
Als `bind`-Addresse macht eigentlich nur 127.0.0.1 oder 0.0.0.0 Sinn, also entweder lokaler Server oder einer der auf alle Adressen hört.
Es sollte keine globalen Variablen geben, zumal `server` gar nicht global gebraucht wird.
conn.recv muß damit zurecht kommen, dass auch weniger als die angeforderten Bytes zurückgegeben werden. `connection` als Flag hat einen komischen Namen, da es sich ja um ein Flag und nicht um eine Verbindung handelt. Andererseits ist das Flag gar nicht nötig, weil man auch eine Endloschleife schreiben könnte, die man per `break` verläßt.
`start` sollte man auch aufrufen, und nakte excepts sind ganz schlecht, weil damit wirklich jeder Fehler verschluckt wird und man keine Chance hat, Programmfehler zu entdecken und zu beheben.
ThePaulCraft
User
Beiträge: 11
Registriert: Samstag 10. Oktober 2020, 17:43

Sirius3 hat geschrieben: Samstag 10. Oktober 2020, 20:11 „Funktionierend” ist eine weit gefasste Definition. Es ist zwar ein bißchen besser als 99.999% aller Beispiele über Socket-Programmierung im Netz, aber immer noch fehlerhaft.
Als `bind`-Addresse macht eigentlich nur 127.0.0.1 oder 0.0.0.0 Sinn, also entweder lokaler Server oder einer der auf alle Adressen hört.
Es sollte keine globalen Variablen geben, zumal `server` gar nicht global gebraucht wird.
conn.recv muß damit zurecht kommen, dass auch weniger als die angeforderten Bytes zurückgegeben werden. `connection` als Flag hat einen komischen Namen, da es sich ja um ein Flag und nicht um eine Verbindung handelt. Andererseits ist das Flag gar nicht nötig, weil man auch eine Endloschleife schreiben könnte, die man per `break` verläßt.
`start` sollte man auch aufrufen, und nakte excepts sind ganz schlecht, weil damit wirklich jeder Fehler verschluckt wird und man keine Chance hat, Programmfehler zu entdecken und zu beheben.
Erstmal danke für die schnelle und ausführliche Antwort! Der nackte except block ist wirklich etwas ungeschickt, zumal der Fehler mit den vergessenen Klammern bei der start Funktion wirklich dämlich und vermeidbar ist. Leider kenne ich mich mit Netzwerk Technik nicht so großartig aus, was das debuggen nicht wirklich erleichtern wird...
Das die recv auch mit anderen Längen zurecht kommen muss ist mir klar, das wäre dann auch der nächste schritt gewesen, die Sache mit der Endlosschleife ist auch nur der Leserlichkeit zur Liebe so geschrieben und die Variable werde ich schleunigst in conected umbenennen. Alles in allem kann ich mich nur sehr über diese Antwort bedanken!
mfg!
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Eigentlich will man gar nicht mit den low-level-Methoden von socket arbeiten, sondern man läßt sich per socket.makefile eine Fileobjekt-ähnliches Interface geben.
ThePaulCraft
User
Beiträge: 11
Registriert: Samstag 10. Oktober 2020, 17:43

Sirius3 hat geschrieben: Samstag 10. Oktober 2020, 20:57 Eigentlich will man gar nicht mit den low-level-Methoden von socket arbeiten, sondern man läßt sich per socket.makefile eine Fileobjekt-ähnliches Interface geben.
Ich wusste gar nicht, dass es in Python Interfaces gibt, allerdings habe ich noch nie von einem File-object ähnlichem Interface gehört bzw. etwas gelesen.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Das gibt es auch nicht als Sprachkonstrukt, weil jedes Objekt, das die entsprechenden Methoden implementiert automatisch auch das entsprechende Interface hat.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

In Python gibt es zwar kein spezielles Schlüsselwort für ein Interface, aber trotzdem zig Umsetzungen von Protokollen / Schnittstellen in Verbindung mit den Dunder-Methoden nach dem Schema __name__(). Eine der bekanntesten dürfte dabei __init__() sein. Die haben halt abhängig von ihrer Benennung alle eine spezielle Bedeutung für den Interpreter. Und bei Dateiobjekten sind es zwar keine Dunder-Methoden, aber eben so Voraussetzungen wie read() und write() und dass man die Zeilen erhält, wenn man über das Objekt iteriert.
ThePaulCraft
User
Beiträge: 11
Registriert: Samstag 10. Oktober 2020, 17:43

Achso, ich glaube ich verstehe was gemeint war.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Als `bind`-Addresse macht eigentlich nur 127.0.0.1 oder 0.0.0.0 Sinn, also entweder lokaler Server oder einer der auf alle Adressen hört.
Es gibt Situationen, bei denen man ausschließlich Verbindungen im LAN haben will, mehr als eine IP verfügbar ist und der offene Port nicht auf den anderen IPs exponiert werden darf.
Ok, ich kann es an einer Hand abzählen, aber es gibt sie.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten