Seite 1 von 2
Kivy: String von .py an Label .kv übergeben
Verfasst: Dienstag 5. September 2023, 22:36
von DMD-OL
Hallo
Ich brauche eure Hilfe bei der Frage, wie ich in meinem verkürzt gezeigten Code, einen vom Server zurückgesendeten String (answer) auf der Python-Seite app_client.py an ein Label (id: input) auf der
Kivy-Seite app_client.kv übergeben kann. Zur verkürzten Darstellung habe ich die Klasse Communication weggelassen.
Hier der Code app_client.py:
Code: Alles auswählen
class FirstScreen(Screen):
def get_communication(self):
if communication.get_ip_address() is True:
self.parent.current = "second"
communication.get_username(self.ids.nickname.text)
receive_thread = threading.Thread(target=communication.receive)
receive_thread.start()
write_thread = threading.Thread(target=communication.write)
write_thread.start()
else:
PopupWindow().open()
class SecondScreen(Screen):
def receive(self, answer):
print(answer)
# self.ids.input.text = answer # ???
def write(self):
communication.write(self.ids.output.text)
@staticmethod
def close():
global connection
connection = False
communication.close()
sys.exit()
class ScreenManagement(ScreenManager):
"""
def __init__(self, *args, **kwargs):
super(ScreenManagement, self).__init__(*args, **kwargs)
@mainthread
def delayed():
first_screen = self.get_screen('first')
second_screen = self.get_screen('second')
delayed()
"""
pass
class ClientApp(App):
def build(self):
return Builder.load_file("app_client.kv")
class PopupWindow(Popup):
pass
if __name__ == "__main__":
communication = Communication()
app = ClientApp()
app.run()
und hier ist der Code app_client.kv:
Code: Alles auswählen
ScreenManagement:
FirstScreen:
name: 'first'
SecondScreen:
name: 'second'
<FirstScreen>
name: "first"
BoxLayout:
orientation: 'vertical'
padding: 25
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .3
Button:
text: '<'
size_hint: .1, 1
font_size: 75
# background_normal: ""
background_color: 1, .5, .92, 1
on_release: app.root.current = root.close()
Label:
text: 'CHOOSE USERNAME'
font_size: 50
canvas.before:
Color:
rgba: 0.18, .5, .92, 1
Rectangle:
pos: self.pos
size: self.size
Widget:
size_hint: .1, 1
canvas.before:
Color:
rgba: 1, .5, .92, 1
Rectangle:
pos: self.pos
size: self.size
GridLayout:
cols: 2
rows: 1
size_hint_y: None
height: 80
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'Username:'
font_size: 40
size_hint: .3, 1
color: 0.18, .5, .92, 1
pos_hint: {'center': 1}
TextInput:
id: nickname
text: "DMD"
size_hint: .6, 1
font_size: 50
multiline: False
Button:
text: '>> Join In'
font_size: 35
size_hint: 1, .3
# background_normal: ""
background_color: 0.18, .5, .92, 1
on_release: root.get_communication()
Label:
text: 'Support'
color: 0.18, .5, .92, 1
halign: 'left'
font_size: 25
size_hint: 1, .3
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
<SecondScreen>
name: "second"
output: output
input: input
BoxLayout:
orientation: 'vertical'
padding: 25
Label:
text: "CHAT ROOM"
font_size: 50
TextInput:
id: output
text: "Your message here..."
font_size: 25
multiline: False
Label:
id: input # hier versuche ich die Serverantwort "answer" zu übergeben
text: "Hello world!"
font_size: 25
Button:
text: ">> Send"
font_size: 35
on_release: root.write()
Button:
text: ">> Close"
font_size: 35
on_release: app.root.current = root.close()
Jede Hilfe ist mir natürlich willkommen

Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 06:06
von Sirius3
Ich kenne mich mit Kivy nicht aus, aber auch sonst gibt es noch viele Baustellen. Auch in kivy darf es keine globalen Variablen geben. sys.exit ist sicher der falsche Weg um ein jivy-Programm zu beenden.
Eine Funktion die get_ip_address heißt, sollte nicht True zurückgeben. Auf True prüft man nicht mit `is`.
Dass der Rückgabewert von get_username nicht verwendet wird, läßt befürchten, dass die Funktion auch nicht das macht, was der Name suggeriert. Dass die Threads keine Argumente haben, deutet auch darauf hin, dass hier mit globalen Variablen gearbeitet wird. Das ist bei Threads nochmal gefährlicher.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 08:37
von Dennis89
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 11:41
von DMD-OL
Wie gesagt, die Klasse Communication fehlt hier. Es wird natürlich alles auch verwendet, was da steht.
Die globalen Variablen sind nur vorerst da enthalten, damit ich es grundsätzlich einmal zum Laufen bekomme.
Danach werde ich versuchen, die rauszuschmeißen.
Zur Funktion kurz:
Es ist eine sehr einfache Server-Client-App (ein kleiner Chatroom).
Mit dem Button '>> Join In' melde ich mich beim Server an. Dann kann ich einen Text schreiben, schicke den über Button ">> Send" zum Server, der mir den Text direkt wieder zurückschickt.
Auf SecondScreen -> def receive(self, answer) kommt derselbe Text wieder an.
Jetzt versuche ich nur noch, den empfangenen Text "answer" an das Label id: input zu übergeben.
So wie ich es hier habe, erhalte ich die Fehlermeldung:
Code: Alles auswählen
Exception in thread Thread-1 (receive):
Traceback (most recent call last):
File "kivy\properties.pyx", line 961, in kivy.properties.ObservableDict.__getattr__
KeyError: 'input'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files\Python310\lib\threading.py", line 1016, in _bootstrap_inner
self.run()
File "C:\Program Files\Python310\lib\threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\dmd__\Documents\Programmierung\PyCharm\Chat-App\client\app\app_client.py", line 46, in receive
self.second.receive(message)
File "C:\Users\dmd__\Documents\Programmierung\PyCharm\Chat-App\client\app\app_client.py", line 80, in receive
hello = self.ids.input
File "kivy\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'. Did you mean: '__setattr__'?
Wo genau ist jetzt das Problem?
Das was ich rausbekommen habe ist, dass ich an die Variable "self.ids.input.text" eine leere Hülle übergebe. Das verursacht den Fehler?
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 13:03
von DMD-OL
@Dennis89
Dein Beispiel konnte ich bei mir umsetzen. Das funktioniert.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 13:36
von DMD-OL
Habs jetzt so. Leider funktioniert es auch nicht.
Code: Alles auswählen
class SecondScreen(Screen):
input = ObjectProperty(None)
def receive(self, message):
print(type(message), message)
# hello = self.ids.input
# hello.text = message
self.input = message
def write(self):
communication.write(self.ids.output.text)
Code: Alles auswählen
<SecondScreen>
input: input
BoxLayout:
orientation: 'vertical'
padding: 25
Label:
text: "CHAT ROOM"
font_size: 50
TextInput:
id: output
text: "Your message here..."
font_size: 25
multiline: False
TextInput:
id: input
text: input.text # Ist hier der Fehler?
font_size: 25
multiline: False
Button:
text: ">> Send"
font_size: 35
on_release: root.write()
Der Button ">> Send" schickt das Geschriebene an die Klasse Communication (die weiter zum Server, der alles wieder zurück an receive(self, message).
Value message ist ein String.
IST MEIN RECHNER KAPUTT?

Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 18:46
von Dennis89
Naja, in der Doku sieht das ein bisschen anders aus, ich kopiere dir die Stelle mal hier rein:
Code: Alles auswählen
<Marvel>
Label:
id: loki
text: 'loki: I AM YOUR GOD!'
Button:
id: hulk
text: "press to smash loki"
on_release: root.hulk_smash()
Code: Alles auswählen
class Marvel(BoxLayout):
def hulk_smash(self):
self.ids.hulk.text = "hulk: puny god!"
self.ids["loki"].text = "loki: >_<!!!" # alternative syntax
Ich verstehe nicht ganz, wenn du den auf deinen "send"-Button klickst, dann soll sich der Text des Labels ändern? Du rufst aber eine "write"-Funktion auf und der Teil zum ändern des Labels steht in einer anderen Funktion, die nicht aufgerufen wird. Wenn du in die Funktion, die nach dem drücken des Buttons aufgerufen wird
Code: Alles auswählen
self.ids.input.text = "Jetzt steht da ein anderer Text"
schreibst, dann steht da im Label mit der id "input" jetzt ein anderer Text.
Zumindest wars bei mir so.
Der Rechner teilst sich in verschiedene Ebenen auf, ich habe gelernt, dass die Ebene 8 öfters kaputt sei.
Grüße
Dennis
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 20:52
von DMD-OL
Ja, wie ich schon geschrieben habe, habe ich das auch gemacht. Das was du da gemacht hast, funktioniert ja auch bei mir.
Zur Beschreibung MEINES Problems:
Mit dem Button "Send" in der Klasse SecondScreen wird das was man im TextInput "output" geschrieben hat, in der Funktion SecondScreen "write" ausgelesen und an die Funktion "write" in der Klasse Communication gegeben. Diese Funktion sendet das Geschriebene an den Server. Der Server wieder direkt alles zurück an die Funktion "receive" in der Klasse Communication. Und von da aus wieder zurück an die Funktion "receive" in der Klasse SecondScreen.
Also:
Button "Send" drücken -> SecondScreen:write-> Communication:write -> Server .> Communication:receive -> SecondScreen:receive [-> von hier aus noch an das Label "input" in .kv-File]
Das heißt drücke ich den Button "Send" geht alles Geschriebene an den Chat-Server und der schickt das wieder zurück an alle beteiligten Chat-Teilnehmer.
Soweit funktioniert alles auch fehlerfrei.
Jetzt fehlt noch, den vom Server zurückgesendeten String "message", der in der Funktion "receive" in Klasse SecondScreen ankommt, an das Label "input" in der .kv-Seite zu geben.
Heißt, ich muss den String "message", der hier ankommt:
Code: Alles auswählen
def receive(self, message):
print(type(message), message)
self.input = message
# hello.text = message
# self.input = message
an das Label input
Code: Alles auswählen
TextInput:
id: input
text: root.input.text # Ist hier der Fehler?
font_size: 25
multiline: False
übergeben.
Hoffe, das ist verständlich

Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 21:29
von DMD-OL
Hier ist der gesamte Code. Ist alles noch sehr verbesserungsnötig, wie ja auch Sirius3 schon geschrieben hat. Vor allem die globalen Variablen müssen später noch weg.
-> app_client.py
Code: Alles auswählen
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
import socket
import sys
import threading
BUFFER = 64
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "exit"
connection = True
class Communication:
def __init__(self):
super(Communication, self).__init__()
self.first = FirstScreen()
self.second = SecondScreen()
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.IP_ADRESS, self.NICKNAME, self.COUMMUNICATION = str(), str(), bool
def get_ip_address(self):
try:
IP = socket.gethostbyname(socket.gethostname())
self.client.connect((str(IP), 50505))
self.IP_ADRESS = IP
self.COUMMUNICATION = True
except socket.error:
self.COUMMUNICATION = False
finally:
return self.COUMMUNICATION
def get_username(self, NICKNAME):
self.NICKNAME = NICKNAME
def receive(self):
global connection
while connection:
message = self.client.recv(1024).decode(FORMAT)
if message == 'NICKNAME':
self.client.send(self.NICKNAME.encode(FORMAT))
else:
self.second.receive(message)
def write(self, user_output=None):
if user_output is not None:
message = f"[{self.NICKNAME}]: {user_output}".encode(FORMAT)
len_message = str(len(message)).encode(FORMAT)
len_message += b' ' * (BUFFER - len(len_message))
self.client.send(len_message)
self.client.send(message)
def close(self):
self.write("exit")
class FirstScreen(Screen):
def get_communication(self):
if communication.get_ip_address() is True:
self.parent.current = "second"
communication.get_username(self.ids.nickname.text)
receive_thread = threading.Thread(target=communication.receive)
receive_thread.start()
write_thread = threading.Thread(target=communication.write)
write_thread.start()
else:
PopupWindow().open()
class SecondScreen(Screen):
input = ObjectProperty(None)
def receive(self, message):
print(type(message), message)
self.input = message # "message" soll jetzt in das Label "input" auf der .kv-Seite
# hello.text = message # Aber nicht so.... :)
# self.input = message
def write(self):
communication.write(self.ids.output.text)
@staticmethod
def close():
global connection
connection = False
communication.close()
sys.exit()
class PopupWindow(Popup):
pass
class ScreenManagement(ScreenManager):
"""
def __init__(self, *args, **kwargs):
super(ScreenManagement, self).__init__(*args, **kwargs)
@mainthread
def delayed():
first_screen = self.get_screen('first')
second_screen = self.get_screen('second')
delayed()
"""
pass
class ClientApp(App):
def build(self):
return Builder.load_file("app_client.kv")
if __name__ == "__main__":
communication = Communication()
app = ClientApp()
app.run()
app_client.kv
Code: Alles auswählen
ScreenManagement:
FirstScreen:
name: 'first'
SecondScreen:
name: 'second'
<FirstScreen>
BoxLayout:
orientation: 'vertical'
padding: 25
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .3
Button:
text: '<'
size_hint: .1, 1
font_size: 75
# background_normal: ""
background_color: 1, .5, .92, 1
on_release: app.root.current = root.close()
Label:
text: 'CHOOSE USERNAME'
font_size: 50
canvas.before:
Color:
rgba: 0.18, .5, .92, 1
Rectangle:
pos: self.pos
size: self.size
Widget:
size_hint: .1, 1
canvas.before:
Color:
rgba: 1, .5, .92, 1
Rectangle:
pos: self.pos
size: self.size
GridLayout:
cols: 2
rows: 1
size_hint_y: None
height: 80
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'Username:'
font_size: 40
size_hint: .3, 1
color: 0.18, .5, .92, 1
pos_hint: {'center': 1}
TextInput:
id: nickname
text: "DMD"
size_hint: .6, 1
font_size: 50
multiline: False
Button:
text: '>> Join In'
font_size: 35
size_hint: 1, .3
# background_normal: ""
background_color: 0.18, .5, .92, 1
on_release: root.get_communication()
Label:
text: 'Support'
color: 0.18, .5, .92, 1
halign: 'left'
font_size: 25
size_hint: 1, .3
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
<SecondScreen>
input: input
BoxLayout:
orientation: 'vertical'
padding: 25
Label:
text: "CHAT ROOM"
font_size: 50
TextInput:
id: output
text: "Your message here..."
font_size: 25
multiline: False
TextInput:
id: input
text: input.text
font_size: 25
multiline: False
Button:
text: ">> Send"
font_size: 35
on_release: root.write()
Button:
text: ">> Close"
font_size: 35
on_release: app.root.current = root.close()
<PopupWindow>
title: "Popup Window"
auto_dismiss: False
size_hint: 0.7, 0.5
pos_hint: {"x": 0.2, "top": 0.9}
FloatLayout:
size_hint: 0.6, 0.8
Label:
text: "Es konnte keine Verbindung hergestellt werden."
text_size: self.width, None
halign: "center"
valign: "middle"
size_hint: 0.6, 0.5
pos_hint: {"x": 0.2, "top": 1}
height: self.texture_size[1]
color: 0.8,0.6,0.1,1
canvas.before:
Color:
rgba: 0.5, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
Button:
text: "Schließen"
size_hint: 0.8, 0.2
pos_hint: {"x": 0.1, "y": 0.1}
on_release: root.dismiss()
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Mittwoch 6. September 2023, 21:51
von Sirius3
Nur Konstanten werden komplett GROSS geschrieben, es ist unsinn, den leeren String per str() zu erzeugen, und COUMMUNICATION den Typ bool zuzuweisen ist totaler Quatsch. Nicht initialisierte Attribute wird None zugewiesen und nichts anderes.
Für Socket-Communication braucht man ein Protokoll. Ein recv(1024) liefert 1 bis 1024 Bytes. Wenn Du versuchst, diese UTF8 zu decodieren kann es zu Fehlern kommen, weil UTF8 Zeichen mit mehr als einem Byte codieren kann.
send sendet 1 bis alle Bytes, das muß man also prüfen, ob wirklich alle Bytes gesendet worden sind, oder sendall benutzen.
Wenn man Zahlen mit einer bestimmten Anzahl an Stellen ausgeben will, benutzt man Formatstrings, in Deinem Fall also:
Die Funktionsnamen sind immer noch schlmm: get_ip_address würde besser connet heißen, den Rückgabewert prüft man immer noch nicht per `is True`. get_username ist eindeutig ein set_username.
Ich denke Kivy ist keine Ausnahme, was Threadsicherheit betrifft. Man darf von keinem anderen Thread auf die GUI zugreifen.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 14:57
von DMD-OL
Bis auf das die Themen Threadsicherheit und Socket-Protokoll habe ich soweit alles erstmal verbessert.
Wie man die beiden übrigen Themen besser macht, weiß ich noch nicht genau. Ein kleiner Tip dazu hätte ich da leider auch noch nötig
Code: Alles auswählen
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
import socket
import sys
import threading
class Communication:
def __init__(self):
super(Communication, self).__init__()
self.first = FirstScreen()
self.second = SecondScreen()
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ip_adress, self.nickname, self.communication = None, None, None
self.format = 'utf-8'
self.connection = True
def connect(self):
try:
IP = socket.gethostbyname(socket.gethostname())
self.client.connect((str(IP), 50505))
self.ip_adress = IP
self.communication = True
except socket.error:
self.communication = False
finally:
return self.communication
def set_username(self, nickname):
self.nickname = nickname
def receive(self):
while self.connection:
message = self.client.recv(1024).decode(self.format)
if message == 'NICKNAME':
self.client.sendall(self.nickname.encode(self.format))
else:
self.second.receive(message)
def write(self, user_output=None):
if user_output is not None:
message = f"[{self.nickname}]: {user_output}".encode(self.format)
len_message = b"%-*d" % (64, len(message))
self.client.sendall(len_message)
self.client.sendall(message)
def close(self):
self.write("exit")
self.connection = False
sys.exit()
class FirstScreen(Screen):
def get_communication(self):
if communication.connect():
self.parent.current = "second"
communication.set_username(self.ids.nickname.text)
receive_thread = threading.Thread(target=communication.receive)
receive_thread.start()
write_thread = threading.Thread(target=communication.write)
write_thread.start()
else:
PopupWindow().open()
class SecondScreen(Screen):
input = ObjectProperty(None)
def receive(self, message):
print(type(message), message)
self.input = message
# hello.text = message
# self.input = message
def write(self):
communication.write(self.ids.output.text)
@staticmethod
def close():
communication.close()
class PopupWindow(Popup):
pass
class ScreenManagement(ScreenManager):
pass
class ClientApp(App):
def build(self):
return Builder.load_file("app_client.kv")
if __name__ == "__main__":
communication = Communication()
app = ClientApp()
app.run()
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 15:29
von __blackjack__
`recv(1024)` ist immer noch falsch. Das geht so schlicht und ergreifend nicht. Du musst ein Protokoll implementieren als Dir überlegen wie Du einzelne Nachrichten aus dem TCP-Datenstrom kennzeichnest und dann Code schreiben der das Nachrichtenformat dann verarbeiten kann.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 16:41
von DMD-OL
??? Was? Ich muss mir ein eigenes Protokoll schreiben. Ich nutze das doch nur privat!
Ich würde auch gern mein eigentliches Problem angehen, wie ich den String message an das TextInput input übergeben kann.
Das funktioniert ja auch noch nicht mal.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 16:44
von __deets__
Was hat das denn damit zu tun? Ohne funktioniert’s halt nicht oder produziert schwer nachvollziehbare Fehler. Und für einen Chat reicht im Zweifel ein readline-basiertes, wie hier schon 1000de Male diskutiert.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 19:12
von DMD-OL
Ich kümmere mich das sehr gern drum. Ich möchte auch einen vernünftig funktionierenden Code habe. Ein eigenes Protokoll zu schreiben, dauert bei mir aber wohl sau lange.
Da sitz ich Jahre dran. Ich nutze doch ein Protokoll das allgemein gültig ist. So wie ich es habe, scheint das so sehr verbreitet zu sein.
Ich würde mich nur freuen, wenn mir vielleicht auch jemand bei meinem eigentlichen Problem helfen könnte.
Da sieht es nämlich auch nicht so gut aus...

Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 20:27
von Dennis89
Hallo,
das mit den Protokollen würde ich nicht vernachlässigen, wenn dir das so ans Herz gelegt wird.
Dann würde ich mal die Threads ganz rauswerfen und die Abfrage der Nachricht regelmäßig mit "Clock" machen:
https://kivy.org/doc/stable/api-kivy.clock.html
Grüße
Dennis
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 21:10
von DMD-OL
Ja, siehe oben.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Donnerstag 7. September 2023, 23:20
von __blackjack__
@DMD-OL: Nein, Du benutzt kein Protokoll, das ist ja gerade das Problem. Das Du in der Transportschicht TCP benutzt hat nichts damit zu tun, dass Deine Anwendungsschicht ein Protokoll braucht um tatsächlich funktionieren zu können. Also über den Zufall hinaus dass das manchmal zu funktionieren *scheint*.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Freitag 8. September 2023, 08:17
von Sirius3
@DMD-OL: bei `write` hast Du doch schon ein Protokoll implementiert, nur bei receive fehlt das noch.
Re: Kivy: String von .py an Label .kv übergeben
Verfasst: Freitag 8. September 2023, 08:33
von __deets__
DMD-OL hat geschrieben: Donnerstag 7. September 2023, 19:12
Ich kümmere mich das sehr gern drum. Ich möchte auch einen vernünftig funktionierenden Code habe. Ein eigenes Protokoll zu schreiben, dauert bei mir aber wohl sau lange.
Da sitz ich Jahre dran. Ich nutze doch ein Protokoll das allgemein gültig ist. So wie ich es habe, scheint das so sehr verbreitet zu sein.
Du hast nicht verstanden, worum es geht. Du sollst nicht das Internet neu erfinden. Sondern dir darueber klar werden, dass Sockets als Abstraktion DatenSTROEME sind. NICHT Pakete. Auch wenn man von TCP/IP-Paketen spricht, gibt dein OS dir einen Gartenschlauch in die Hand, aus dem mal ein paar Tropfen kommen, mal ein ganzer Schwall. Aber *NICHT* bei jedem mal benutzen eine genau definierte Menge, also in deinem Fall genau *eine* Nachricht. Das ist reiner Zufall, dass das meistens funktioniert. Protokoll meint also hier, dass man auf diesem Datenstrom obendrauf etwas packt, das sicherstellt, dass man immer eine komplette Nachricht empfangen hat. ZB indem man alle Nachrichten konsisten mit einem Zeilenvorschub beendet, und dann kann man auch einfach so lange lesen, bis der kommt, und fertig ist das Protokoll.
Um es nochmal ganz ganz deutlich zu sagen: wenn du 100 Bytes in den Socket schreibst (mit send_all, sonst ist noch nicht mal garantiert, das alles reingeschrieben wird), dann koennen da beim lesen
- 100 byte am Stueck kommen (nimmst du gerade an)
- 1 Byte, 10 Byte, 89 Byte
- 23 Byte, 77 Byte.
Und so weiter.