Chat Skript funktioniert nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Tom12
User
Beiträge: 48
Registriert: Mittwoch 17. Januar 2018, 17:38

Hallo,
ich programmiere derzeit einen kleinen Messenger, also zwei Computer welche miteinander kommunizieren sollen, ich habe nun dieses Script als "Client"

Code: Alles auswählen

import socket

socket_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_addr = ("192.162.134.28", 137)
socket_client.connect(server_addr)
Eingabe = input()
socket_client.send(bytes (Eingabe, "utf8"))
while True:
    Rückgabe = socket_client.recv(1024)
    print(Rückgabe)
und als "Server-script"

Code: Alles auswählen

import socket

socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_server.bind(("192.162.134.28", 137))
socket_server.listen(1)
while True:
    (socket_client, addr) = socket_server.accept()
    (socket_client2, addr) = socket_server.accept()
    EingabeC = socket_client.recv(1024)
    print(EingabeC)
    socket_client.send(EingabeC)
    socket_client2.send(EingabeC)
nun kann ich Nachrichten an den Server senden diese kommen dort auch an aber beim 2. Client wird nur b ' ' gespamt, da sich die while schleife ja wiederholt, wie kann ich es lösen, dass der Client jede Nachricht nur einmal ausgibt ?
in der while Schleife eine if Abfrage ?

Bitte um Hilfe
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tom12: so funktioniert Socket-Programmierung nicht. Bei TCP gibt es keine Nachrichten, sondern wie das Argument schon sagt, nur einen Stream, also viele Bytes hintereinander, ohne Abgrenzung. Will man also wirklich Nachrichten versenden, braucht mein ein Protokoll, am einfachsten ein Zeilenbasiertes, wobei man über makefile sich ein normales Fileobjekt geben läßt.

Den Server an eine konkrete Addresse zu binden ist auch falsch, meist wird 0.0.0.0 verwendet. Du vergißt, die Clientsockets im Server wieder zu schließen.

Vom zweiten Client sehe ich nichts, so dass ich zu Deinem konkreten Problem auch nichts sagen kann. Leere Ergebnisse gibt es aber immer dann, wenn der Server die Verbindung schon wieder geschlossen hat.
Tom12
User
Beiträge: 48
Registriert: Mittwoch 17. Januar 2018, 17:38

Sirius3 hat geschrieben:Will man also wirklich Nachrichten versenden, braucht mein ein Protokoll, am einfachsten ein Zeilenbasiertes, wobei man über makefile sich ein normales Fileobjekt geben läßt.
tut mir leid, aber leider komme ich mit dieser Aussage nicht mit. Wo muss das Protokoll erstellt werden vom Server Script? welchen Zweck hat es? Und was soll darin gespeichert werden ?
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein Protokoll ist eine Vereinbarung darueber, wie Nachrichten aussehen. Du *glaubst* wenn du recv(1024) aufrufst, dann bekommst du immer die naechste, und natuerlich auch genau eine Nachricht. Stimmt halt nicht. Das OS kann sich entscheiden (bzw. wird dazu gezwungen, durch Eigenheiten deines Netzwerks etc), dir nur einen Bruchteil der Daten zu geben. Oder mehrere Nachrichten nacheinander, weil du schneller gesendet als empfangen hast. Und ganz offensichtlich duerfen deine Nachrichten auch nicht groesser als 1024 sein, sonst bekommst du auch nur Stueckwerk.

Um die daraus resultierenden Probleme zu loesen, fuehrt man ein Protokoll ein. Das besagt, wie man die einzelnenen Nachrichten darstellt und dann abrufen kann.

Fuer dein Programm kann es etwas simples sein, was Sirius3 schon vorgeschlagen hat: lese alle Zeichen bis zu einem Neue-Zeile-Zeichen. Das ist das Kriterium dafuer, dass eine Nachricht komplett ist, und alles, was danach kommt, schon zur naechsten gehoert. Eine Eigenschaft dieses Protokolls ist es, das man keine Nachrichten verschicken kann, in denen wiederum Neue-Zeile-Zeichen als Inhalt vorkommen duerfen. Fuer ein chat-Programm ist das vertretbar. Fuer generelle Nachrichten eher nicht, eine Email die nur eine Zeile hat ist unlesbar. Dementsprechend ist die Darstellung etwas komplizierter. Schoen farbig erklaert zB hier: https://de.wikipedia.org/wiki/Header_(E-Mail)

Und um die konkrete Frage nach dem "wo" zu beantworten: alle Beteiligten muessen sich einig sein, wie das Protokoll aussieht. Also sowohl server als auch client. Wobei der Server bei dir ja nur durchreiche ist, der kann auch dumm bleiben.
Tom12
User
Beiträge: 48
Registriert: Mittwoch 17. Januar 2018, 17:38

ok,
da ich mich in das Thema socket einarbeiten wollte, und die Sache mit den Protokollen zu kompliziert ist, werde ich dieses Projekt vorerst ruhen lassen :D

Habt ihr andere Ideen für kleinere Projekte Thema Socket ? Möchte mein Wissen in diesem Bereich etwas ausweiten
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eigentlich ist das das Thema socket. Sie richtig zu nutzen gehoert nunmal dazu. Und eher frueher als spaeter (zb wenn dein Chat-Programm einen File-Upload spendiert bekommen soll, oder zB animierte GIFs versenden soll) muss man das halt richtig machen.

Wobei das ja nun auch nicht wirklich Raketenwissenschaft ist:

1 lese einen Datenblock
2 haenge ihn an die schon gelesenen Daten ran.
3 schau ob eine neue Zeile drin ist.
4 trenn die Daten daran auf, und verarbeite die Nachricht. Der rest wird wieder zu den schon gelesenen Daten.
5 gehe nochmal zu 3, koennten ja mehrere Zeilen sein.

Du kannst natuerlich auch einfach jedes gelesene Byte hin und herschaufeln fuer den Anfang. Aber wie gesagt, wirklich gehen tut das nur fuer trivialen Kram, man muss sich der Grenzen da schon bewusst sein.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tom12: Du wolltest also Autofahren lernen, aber die Sache mit den Verkehrsregeln ist Dir zu kompliziert? Egal, was Du mit sockets machst, eine Vereinbarung darüber, wie die Daten strukturiert sind, braucht man immer. Wenn Du Dich ganz low-level mit Sockets beschäftigen willst, gehört das dazu. Wenn man das nicht möchte, dann steigt man zwei bis drei Ebenen höher ein und nimmt ein fertiges Modul, das ein bestimmtes Protokoll schon umsetzt. Das simpelste, Sockets einfach wie Dateien zu behandeln, hab ich Dir schon gezeigt: makefile.
Antworten