Wirrwarr-zeichen bei anzeige von string der über winsock geschickt wurde^^



  • ich hab frage:

    ich hab mir ne kleine class zu nem socket von TCP geschrieben un dann mal getestet oder die einwandfrei läuft. hab mit ner andren datei nen string geschickt un mit der class recvivt un ihn dann angezeigt mit win32 (edit). es kamen aber nur wirrwar r zeichen wie ì un en viereck :(:( ( die zeichen sind warsceinlich DOS zeichen die unter win32 ausgegeben wurdn)
    aber was ham die hier verloren ??

    danke ,,, christoph 😉



  • Du machst was falsch. Entweder beim Senden, beim Empfangen oder beim Schreiben in die Datei.
    -.-



    1. das war mir fast klar dass ich was falsch mach *g*
    2. ich schreib den string nicht in eine datei, ich geb ihn nur via edit-box aus.
      3)hier ein kleiner ausschnitt:

    [cpp]
    SOCKET remote[MAXREMOTES];
    ...
    int remotes;
    ...
    if(listen(s,10)==SOCKET_ERROR)
    return false;
    remote[remotes+1]=accept(s,NULL,NULL);
    remotes++;
    if (remote[remotes+1]==INVALID_SOCKET)
    return false;
    return true;
    ...
    server1.recvs((char*)buf,0);
    MessageBox(0,buf,buf,MB_OK);

    un da kommt scheisse raus (in buf)



  • Ich weiß zwar nicht, was server1 für ein Typ ist, oder was recvs genau macht, aber ich nehme mal an, dass der zweite Parameter in recvs die Größe des Buffers erwartet. In einen 0 byte langen Buffer schreibt die Funktion nichts.

    Edit:
    Was wohl auch nicht so gedacht ist, ist folgender Abschnitt:

    remote[remotes+1]=accept(s,NULL,NULL);
    remotes++;
    if (remote[remotes+1]==INVALID_SOCKET)
    


  • ok es ist ein bissle verwirrend
    die class "Ctcp" (server1 ist eine instanz also abbildung) is eine klasse eines serversocket der alle sockets ,die auf ihn konnekten, in eine SOCKETarray speichert.
    der 2. parameter bedeutet: welscher SOCKET der array soll recviven.
    Weil remote[0] der 1. un einzigste socket -in diesem fall- in der array is muss also eine 0 hin.

    "remotes" speichert die anzahl der sockets die in der array gespeichert sind. konnektet ein neuer socket so wird er in remote[remotes+1] gespeichert

    ps.: ich bin kein guter erklärer, wenn du dich damit abgeben kannst dann weiss ich dass es auch noch gute menschen da draussen gibt 😉

    cu,,,christoph



  • Was ist denn "buf" für ein Typ?



  • "char buf[512];"

    bei "char *buf" bekomm ich nämlich nen runtimeerror



  • also ich will noch erwähnen dass ich bei recv den lenght parameter auf 4 gestellt hab un von nem client "hey" geschickt hab. es kommen aber so ca. 150 ì's dabei raus.

    sry wegen doppelpost



  • vielleicht hast du irgendwo einen fehler gemacht.



  • Fachmann schrieb:

    "char buf[512];"

    bei "char *buf" bekomm ich nämlich nen runtimeerror

    Warum der Typecast in
    server1.recvs((char*)buf,0); ?
    Gabs vorher eine Fehlermeldung?



  • nene das " (char*) " ist überflüssig ich habs nur grunds spontanen experimente verwendet un dann vergessen wieder zu entfernen

    ja ich glaub auch dass ich irgentwie ein fehler gemacht hab aber ich suche schon seit tagen^^ so is das bei mir: ein zehnte der zeit programmier ich an nem projekt un die restiliche neun zehntel such ich die fehler die ich gemacht hab^^



  • Ich möchte nochmal auf msdn-infos zu recv() aufmerksam machen:

    If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero.

    und:

    For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently available — up to the size of the buffer specified.

    Sagen wir mal du sendest "HEY\0" ('\0' - String-Terminierungszeichen).
    Das wären 4 Bytes.

    Dein Buffer bei recv() sagen wir mal wäre 512 Bytes groß.
    Nun kann recv() aber z.B. alle 4 Bytes auf einmal empfangen und in den Buffer schreiben, oder aber recv() empfängt erstmal 2 Bytes und bei einem weiteren Aufruf die nächsten 2 Bytes.
    Wenn man nun z.B. nach einem recv() den buffer via MessageBox() ausgibt, und recv() hat erst 2 bytes empfangen, dann fehlt das String-Terminierungszeichen und er zeigt Blödsinn an 😉



  • das hört sich vielversprechend an! ich probier ma rum un wenns klappt meld ich mich wieder 😉 thx



  • aber wenn ich 4 bytes schicke , die von einem recv befehl recvivt werden dann muss ich doch davon ausgehen dass die 4 bytes im buffer sind wenn der befehl "recv" beeendet is? recv kann ja nicht die hälfte recviven un dann returnen un dann weitermachen mmhm? 😞



  • Ja, wenn recv() als Rückgabewert ne 4 zurückgibt, dann hat recv() auch 4 Bytes im Buffer. Aber das ist halt nicht unbedingt gegeben dass die Buffer-Länge die man als Parameter angibt auch den gleichen Wert wie der Rückgabewert hat...

    recv() hat halt keine Ahnung davon was wohl auf irgendeinem Rechner (auch wenn es derselbe Rechner ist) wohl mit send() verschickt worden ist. Da kann es auch schonmal passieren das selbst bei lokalen Verbindungen schonmal nicht alles sofort da ist - recv() weiss ja nicht wann es vollständig ist - Das weiss ja nur dein Programm.



  • ok stimmt
    also ich hab per send "hi" geschickt (un 3 bei len eingegebn (logisch))

    recv return nicht 3 also bin ich schon ein schritt weiter , nur wie behebt man das? ^^

    ...ich hatte eig gedacht recv weiss wieviel zeichen es bekommt weil die länge des tcppacketes doch im header des packetes gespeichert ist oder?

    thx;), chr

    ::edit::
    ok recv muss die länge doch nicht wissen, sie bekommt sie ja per parameter
    ::edit::
    aber wie behebt man das bzw was kann man tun?



  • Wenn du weisst dass du 4 Bytes kriegen wirst, dann wiederholst du einfach recv() solange bis du genügend Bytes zusammen hast 😉

    Irgendwie so könnte ich mir das vorstellen (Ich hoffe du hast Ahnung von Pointern ;D):

    int ByteCount; // Anzahl der bereits empfangenen Bytes
    int retval; // Rückgabewert von recv()
    char MeinBuffer[10]; // Buffer mit Platz für 10 Bytes
    
    ByteCount=recv(socket,MeinBuffer,10,0);
    while (ByteCount<4)
    {
        retval=recv(socket,MeinBuffer+ByteCount,10,0);
        if (retval==SOCKET_ERROR)
        {
            // Möööp, nen Fehler mit der Verbindung!
        }
        else if (retval==0)
        {
            // Verbindung wurde geschlossen
        }
        else
        {
            ByteCount=ByteCount+retval;
        }
    }
    


  • also lieber geekky, erstmal danke fürn aufwand

    das hörst sich sicher und gut an aber dazu muss man ja wissen wieviel bytes geschickt wurden, das is ja scheisse , bei nem chat^^ , irgentwie machen einem so sachen ganz nicht mehr programmieren wollend^^ ...ich glaub ich steig um auf logo;)

    ...also ich versuch deine methode ma un sag ma danke

    ps.: ja ich hab ne ahnung von pointern 😉


Log in to reply