[SOCKETS] einzelnes Paket erzwingen



  • Hallo Leute,

    wenn ich schnell hintereinander (in einer Schleife) kurze Strings über send sende kommt das ganze als 1 Paket an...

    Ich möchte aber dass jedes Paket einzeln gesendet wird und ich es auch wieder einzeln auslesen kann (recv)

    MfG Rodney



  • Du verstehst TCP falsch. Das ist kein paketorientiertes Protokoll, sondern ein Byte-Strom. Es wird natürlich intern über IP, also Pakete, abgewickelt, aber du kannst dich nicht auf eine bestimmte Art und Weise, in der das passiert, verlassen. Die Pakete könnten beliebig zusammengefasst oder getrennt werden. Je eher du das akzeptierst, desto besser.

    Eine Möglichkeit wäre, vor dem String jeweils die Länge als Einzelbyte (-word, oder was auch immer) zu senden.



  • Bashar schrieb:

    Du verstehst TCP falsch. Das ist kein paketorientiertes Protokoll, sondern ein Byte-Strom. Es wird natürlich intern über IP, also Pakete, abgewickelt, aber du kannst dich nicht auf eine bestimmte Art und Weise, in der das passiert, verlassen. Die Pakete könnten beliebig zusammengefasst oder getrennt werden. Je eher du das akzeptierst, desto besser.

    Eine Möglichkeit wäre, vor dem String jeweils die Länge als Einzelbyte (-word, oder was auch immer) zu senden.

    TCP ist mir eigentlich schon recht klar... 😉
    Trotzdem hätte ich jetzt gedacht, man kann es explizit anfordern dass das Paket einzeln gesendet wird 😕

    Wie kann ich denn am besten den Sendestring unterteilen, mit Trennzeichen (|) ist das eigentlich immer schlecht...

    Und es ist ja vorher nicht definiert wie viele Zeichen kommen.



  • wie werden denn üblicherweise die Nachrichten getrennt?

    In meinem Fall:

    Ich hab ein "Protokoll" was folgendermaßen aussieht:

    nUsername // hier meldet sich Username an, n=anmelden
    aUsername // hier meldet sich Username ab, a=abmelden

    wie kann ich es dann treffen wenn auf einmal so etwas ankommt

    nUsernamaUsername



  • oder du nimmst udp und bastelst damit ein einfaches protikoll, dass empfangene pakete bestätigt. ist nicht so schwer



  • net schrieb:

    oder du nimmst udp und bastelst damit ein einfaches protikoll, dass empfangene pakete bestätigt. ist nicht so schwer

    wär ne möglichkeit, allerdings bin ich jetzt bei tcp, und ich denke das mit dem trennen müsste auch recht einfach möglich sein.

    Nur komm ich mit den Strings noch nicht so ganz klar, deswegen weiß ich nicht wie ich das ganze zerteilen soll...



  • Rodney schrieb:

    Nur komm ich mit den Strings noch nicht so ganz klar, deswegen weiß ich nicht wie ich das ganze zerteilen soll...

    du könntest ja z.b. die strings einschliesslich ihrer 0 am ende mitschicken. wenn du sonst keine binärdaten dranhängen willst ist das wohl am einfachsten



  • net schrieb:

    Rodney schrieb:

    Nur komm ich mit den Strings noch nicht so ganz klar, deswegen weiß ich nicht wie ich das ganze zerteilen soll...

    du könntest ja z.b. die strings einschliesslich ihrer 0 am ende mitschicken. wenn du sonst keine binärdaten dranhängen willst ist das wohl am einfachsten

    das mit dem verschicken ist mir klar, ich weiß nur nicht wie ich das ganze dann trennen soll... Ich arbeite zurzeit noch mit 0-termin. Char-Arrays, da sieht das ganze mit den Strings ziemlich kompliziert aus...

    Ich hab mir jetzt überlegt ganz am Anfang noch ein # davorzusetzen damit ich das ganze besser identifizieren kann also

    #dUsername#nUsername ...

    nur wie trenne ich das ganze jetzt?? Ich hatte da mal ne Funktion strtok oder so, ist aber äußerst unschön, wenn dann Fehler im String sind schmiert das ganze Programm wegen ner Zugriffsverletzung ab...



  • wenn du die nullen mitschickst, dann liesst du solange die bytes ein, bis eine null kommt. dann ist der string fertig und du kannst den nächsten einlesen. bei tcp/ip geht nichts verloren. wenn aus irgendeinem grund die verbindung abbricht wird der string, der gerade in bearbeitung ist verworfen.

    ...aber da gibt es viele andere möglichkeiten. man könnte z.b. vor jedem string die länge schicken (als 2 bytes etwa) und dann die null weglassen. ist auch nicht schlecht



  • net schrieb:

    wenn du die nullen mitschickst, dann liesst du solange die bytes ein, bis eine null kommt. dann ist der string fertig und du kannst den nächsten einlesen. bei tcp/ip geht nichts verloren. wenn aus irgendeinem grund die verbindung abbricht wird der string, der gerade in bearbeitung ist verworfen.

    ...aber da gibt es viele andere möglichkeiten. man könnte z.b. vor jedem string die länge schicken (als 2 bytes etwa) und dann die null weglassen. ist auch nicht schlecht

    die Lösung mit dem \0 am Ende gefällt mir am Besten, nur weiß ich jezt eben nicht genau wie ich das code-mäßig realisieren könnte....



  • nimm dir doch ein beispiel an HTTP



  • oder?? schrieb:

    nimm dir doch ein beispiel an HTTP

    mhh jetzt das komplette HTTP-Protokoll reinziehen... naja 🙄 😡



  • ich kenn das auch nicht so gut.

    ich glaube:

    im header werden die einzelnen zeilen mit \r\n getrennt. und dann kommt zum schluß des header \r\n\r\n und dann die daten



  • oder?? schrieb:

    ich kenn das auch nicht so gut.

    ich glaube:

    im header werden die einzelnen zeilen mit \r\n getrennt. und dann kommt zum schluß des header \r\n\r\n und dann die daten

    ok, aber bringt mich das jetzt irgendwie weiter^^ 🙄

    Ich wollte eigentlich ja nur noch wissen wie ich
    #nUsername#dUsername

    schön sauber zersplitten kann...



  • daten = webseite



  • mit c++ strings geht das nur sauber



  • oder?? schrieb:

    mit c++ strings geht das nur sauber

    hat denn jemand nen beispiel wie man das damit macht?



  • Rodney schrieb:

    die Lösung mit dem \0 am Ende gefällt mir am Besten, nur weiß ich jezt eben nicht genau wie ich das code-mäßig realisieren könnte....

    also empfangsseitig hab mal was hingehackt:

    int recvstring (SOCKET sock, char *s, int maxlen)
    {
    	int i = 0;
    	while (i < maxlen)
    	{
    		int res = recv (sock, &s[i], 1, 0);
    		if (res == 0)
    			return 0;
    		if (res == SOCKET_ERROR)
    			break;
    		if (s[i] == '\0')
    			return 1;
    		i++;
    	}
    	s[0] = '\0';
    	return 0;
    }
    

    aus'm kopf, wahrscheinlich fehlerhaft, aber so könnts gehen.
    (aber keine 2 nullen nacheinander senden)
    rückgabe: 1: es sind noch mehr strings da
    0: keine strings mehr da, verbindung normal beendet.
    0 und s[0] == 0: fehler, entweder string zu lang oder SOCKET_ERROR

    aufruf um einen string zu lesen:

    char s[256];
    recvstring (socket, s, sizeof(s));
    

    dann steht der string in 's'.
    musst halt noch 'ne schleife drumbasteln und immer neuen
    speicher übergeben (malloc oder statisches array oder wie auch immer)

    edit: senden ist ja trivial

    send (socket, string, strlen(string)+1, 0);
    


  • net schrieb:

    Rodney schrieb:

    die Lösung mit dem \0 am Ende gefällt mir am Besten, nur weiß ich jezt eben nicht genau wie ich das code-mäßig realisieren könnte....

    edit: senden ist ja trivial

    send (socket, string, strlen(string)+1, 0);
    

    Muss beim Senden nicht auch eine Schleife machen?

    If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len.



  • Socket-Neuling schrieb:

    net schrieb:

    edit: senden ist ja trivial

    Muss beim Senden nicht auch eine Schleife machen?

    ja, ich meinte nur für einen string + der null.


Log in to reply