pop und smtp Server connecten



  • Wie und Wieso muss ich hier Speicher reservieren?

    für solche Dinge schaust du am besten in dein C oder C++ Buch, was du zum lernen benutzt 🙄

    ich geh mal davon aus, dass du weisst was Pointer sind (du benutzt ja auch welche 🙄 ), wenn du folgenden Code hast

    char *foo;
    

    hast du einen unintialisierten Pointer der zeigt irgend wohin in den Speicher, wenn du nun versuchst ihn zu dereferenzieren, dann hast du auf einmal ein Problem. Also müssen wir den Pointer auf was zeigen lassen, damit wir ihn wirklich nutzen können. Du machst nun folgendes

    char *foo="";
    

    nun zeigt foo auf den konstanten String "" irgend wo im Speicher ("" ist ja gleich 0 vom Wert, also wurde 1 byte Speicher reserviert vom Compiler). Du willst nun irgend was dazu hinzufügen, mit strcat, da aber nun nur 1 byte Speicher reserviert ist und strcat mehr Speicher versucht zu benutzen, hast du ein Problem.

    Was machen wir nun? Wir wollen uns Speicher reservieren, wo strcat genug Platz hat die anderen Strings anzufügen.

    Wie das geht erfährst du hier http://www.schornboeck.net/ckurs/alloc.htm

    hoffe, du hast nun das "Wie" und "Wieso" verstanden



  • Hi !

    Ohne die Details deiner Socketlibrary zu kennen.. versuchs mal so:

    ueps schrieb:

    [...]
    EXPORT char* CALLBACK net_receive(SOCKET s)
    {
    long rc;
    char recv_buf[1024];

    bytes = recv(s, recv_buffer, sizeof(buffer)-1, 0);
    // recv returned -1 bei fehler
    if (bytes>0)
    buffer[bytes] = '\0'; // ende des strings markieren

    return *recv_buf;
    }
    [...]



  • Hier findest du die RFC zu POP. Laut Abschnitt 3 sieht das Verbindungsschema so aus:

    Server: [wartet auf Verbindungen]
    Client  -- verbindet sich zum --> Server
    Server -> Client: Hallo (Greeting)
    Client -> Server: Befehle
    

    du musst also gleich nach dem connect ein receive machen, sonst wird das nix 🙂



  • Hi, danke euch erstmal.

    Ich habe inzwischen was vom Server zurückbekommen, ein fröhliches:

    x‼+OK QPOP (version 3.1) at server.blablabla starting.

    Allerdings hab ich jetzt meine net_receive Methode nicht mehr als while Schleife sondern nen einzelnen Aufruf von recv(...). Warum hat er dass als Schleife nicht auch gemacht? Wenn keine Bytes mehr gelesen werden können müsste doch die Schleife beendet werden, gab allerdings immer ne Endlos Schleife? Jedenfalls würd ich halt gern alle Bytes in einem Rutsch lesen und komplett zurückgeben, das obige Beispiel ist ja auf 1024 Bytes beschränkt?

    Hab gerade herausgefunden dass beim zweiten Schleifen durchlauf die Schleife beim rc=recv(s,recv_buf,256,0); hängen bleibt? Warum dass denn? Bei einem HTTP Request kommt 0 zurück wenn nix anliegt, bei pop hängt sich alles auf oder wie?

    Gruß,
    ueps



  • Hi !

    Das Defaultverhalten der Sockets ist, dass sie im "blockingmodus" arbeiten. Das heißt, dass recv halt solange wartet bis endlich mal ein paar Bytes über die Leitung tröpfeln. Aber keine Angst, nach 3 Minuten läuft ein interner Timeout ab, und die Funktion beendet sich (toll, oder?)
    Wenn dir dieser Wert zu lang ist, musst du selbst dafür sorgen dass recv zurückkehrt (oder erst gar nicht aufgerufen wird) wenn keine Daten kommen.
    Unter Linux kannst du das mit der der Funktion alarm oder select machen.
    In Windows geht das natürlich nicht, evtl. wäre da die Beste Lösung recv eine Callback Funktion aufrufen zu lassen wenn Daten kommen (siehe MFC C(Async)Socket)



  • Hi,

    also dass mit den 3 min ist ja wohl ... Ich frage mich bloß warum beim GET Request an einen Webserver mit receive 0 zurück kommt wenn nix mehr anliegt und bei einem pop Server nicht, ist irgendwie blöd. Wie hast du dass mit der CALLBACK Funktion gemeint? Hab das irgendwie nicht ganz verstanden. Ich muss ja fast ne Schleife mit recv() durchlaufen sonst kann ich ja nie Mails > 255 anzeigen lassen?

    Gruß,
    ueps



  • ueps schrieb:

    Hi,
    also dass mit den 3 min ist ja wohl ... Ich frage mich bloß warum beim GET Request an einen Webserver mit receive 0 zurück kommt wenn nix mehr anliegt und bei einem pop Server nicht [...]

    Das liegt wohl daran, dass der Webserver die Verbindung sofort wieder schließt nachdem er dir Daten geschickt hat. Mach doch einfach mal einen Feldversuch mit telnet webserver 80 😉

    ueps schrieb:

    [...]
    Wie hast du dass mit der CALLBACK Funktion gemeint? Hab das irgendwie nicht ganz verstanden.
    [...]

    Wie ichs gesagt habe, wenn Daten ankommen ruft deine Socketlib automatisch eine Userdefined Funktion auf...

    ueps schrieb:

    [...]
    Ich muss ja fast ne Schleife mit recv() durchlaufen sonst kann ich ja nie Mails > 255 anzeigen lassen?

    Du könntest natürlich auch den Empangsbuffer vergrößern, wenn ich mich recht erinnere konnte ich mit den MFC Socketklassen maximal ~38KB auf einmal verschicken.
    Aber wenn ich mich nicht täusche, wird recv mehrmals aufgerufen wenn du nicht alle Daten auf einmal holst (Angabe ohne Gewähr)



  • RFC1939:

    Responses may be up to 512 characters
    long, including the terminating CRLF.



  • Also mehr wie 256 Byte auf einmal sollte man nicht mit recv lesen.
    Ich hab eben was von einem Paramter O_NONBLOCK gelesen, wenn der beim socket file decriptor gesetzt ist wird nicht 3 min gewartet. Allerdings hab ich nicht gefunden wie man den Wert setzt?

    Hab eben mal was getestet und musste feststellen dass sich alles sehr sehr merkwürdig verhält, hier der Testcode:

    EXPORT int CALLBACK pop_connect(char* ip, int port, char* user, char* passwd)
    {

    long rc;
    char result[256];
    char buf[256];
    char buf2[256];

    rc=startWinsock();
    mail_s = net_connect(ip, port);

    rc=recv(mail_s,result,256,0);
    printf("%s\n",result);

    sprintf(buf,"USER %s\r\n", user);
    printf("send: %s\n", buf);
    rc=net_send(mail_s, buf);

    //Kritische Stelle
    rc=recv(mail_s,buf2,256,0);
    printf("%s\n",buf2);

    sprintf(buf,"PASS %s\r\n", passwd);
    printf("send: %s\n", buf);
    rc=net_send(mail_s, buf);

    rc=recv(mail_s,result,256,0);
    printf("%s\n",result);

    strcpy(buf,"LIST\r\n");
    rc=net_send(mail_s, buf);

    rc=recv(mail_s,result,256,0);
    printf("%s\n",result);

    return 1;
    }

    Die Kritische Stelle habe ich kommentiert, steht dort anstatt buf2 result, geht die Passwort abfrage nicht?!? Gott weiß warum, result und buf haben rein gar nichts miteinander zu tun?!?!?

    Hier mal die Konsolen ausgabe:

    +OK QPOP (version 3.1) at t28.server starting.

    send: USER ueps

    |í║
    send: PASS poppasswd

    +OK selb has 0 visible messages (0 hidden) in 0 octets.
    rting.

    +OK 0 visible messages (0 octets)
    hidden) in 0 octets.
    rting.

    Das kryptische |í║ sollte Passwort required heißen, wie gesagt lass ich statt buf2 result stehen, steht das kryptische statt PASS poppasswd.

    Keine Ahnung was da wieder abgeht.



  • Ich glaube ich weiß was dein Fehler ist, bei send und recv musst du als 3 Parameter nicht die größe des Arrays übergeben, sondern die Größe - 1... also jeweils 255.
    Außerdem wäre es toll wenn du die Strings noch mit \0 terminieren würdest, sonst weißt du nachher nicht wo das Ende des Strings ist, kein sehr praktischer Zustand.

    Also müsste deine kritische Stelle in etwa so aussehen:

    rc=recv(mail_s,buf2,255,0);
    if (rc>0)
         buf2[rc] = '\0';
    printf("%s\n",buf2);
    

    Ich hoffe das wars 😉



  • Jepp, dass mit dem \0 Terminieren vergess ich immer, nen char[5] kann man dann theoretisch ja nur einen 4 stelligen String haben weil ja noch \0 dazu kommt, was bei mir immer wieder zu Fehlern führt 😞 Ich bin halt noch die easy Deklaration von VB , PHP und Cop gewohnt 😉

    Das mit der Länge bei recv dürfte eigentlich egal sein, da ja bis max. 512 Zeichen versendet werden dürfen laut RFC. Warum muss ich 1 Byte von der Länge abziehen?

    Gruß,
    ueps



  • ueps schrieb:

    [...]
    Warum muss ich 1 Byte von der Länge abziehen?

    Weil du doch noch den \0 setzen musst...


Anmelden zum Antworten