Mit Zeitserver verbinden Fehler: 10060,10061



  • Hallo,

    ich möchte,dass sich mein Programm die Atomzeit von einem dieser http://timeserver.verschdl.de/ Server holt, aber es gibt mir immer wieder und bei verschiedenen IP's und Ports, die im Titel angegebenen socket error Nummern zurück.

    Kann mir vlt. jemand sagen was ich falsch mache? Habe echt zu wenig Infos zum Thema.....

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <winsock2.h>
    
    int startWinsock(void)
    
    {
    
      WSADATA wsa;
    
      return WSAStartup(MAKEWORD(2,0),&wsa);
    
    }
    
    int startWinsock(void);
    
    int main(int argc, char *argv[])
    {
    
      long rc;
    
      SOCKET s;
    
      SOCKADDR_IN addr;
    
      char buf[256];
    
      rc=startWinsock();
    
      if(rc!=0)
    
      {
    
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
    
        return 1;
    
      }
    
      else
    
      {
    
        printf("Winsock gestartet!\n");
    
      }
    
    s=socket(AF_INET,SOCK_STREAM,0);
    
    if(s==INVALID_SOCKET)
    
    {
    
      printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
    
      return 1;
    
    }
    
    else
    
    {
    
      printf("Socket erstellt!\n");
    
    }
    
    memset(&addr,0,sizeof(SOCKADDR_IN));
    
    addr.sin_family=AF_INET;
    
    addr.sin_port=htons(37); 
    
    addr.sin_addr.s_addr=inet_addr("146.83.8.200"); 
    
    rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
    
    if(rc==SOCKET_ERROR)
    
    {
    
      printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
    
    }
    
    else
    
    {
    
      printf("Verbunden mit .....");
    
    }
    
    rc=recv(s,buf,256,0);
    
    printf("%s",buf);
    
    system("PAUSE");	
      return 0;
    }
    


  • (NTP) The protocol uses the User Datagram Protocol (UDP) on port number 123.

    Du müsstest einen Server finden der über das "Time Prototocol" arbeitet. Da gibts das mit Port 37 auf TCP.



  • z.B. ptbtime1.ptb.de (192.53.103.108)



  • Vielen Dank, nun funktioniert es prächtig.
    Aber warum ging es dann auch nicht als ich Port 123 verwendet habe?

    Nun habe ich noch ein Problem. Ich bekomme einen String aus Buchstaben. Ich habe vermutet, dass die Asci Codes der Buchstaben dann die Zeit ergeben. Aber wie wandle ich den String bloß in eine Zahl um? Atoi geht nicht da der String aus Buchstaben besteht. sscanf funktioniert auch nicht. Warum? Schließlich würde noch die Möglichkeit bleiben, die Einträge des arrays einzeln zu casten, (Wie man ein ganzes array castet weiß ich nicht) und dann die integers aneinaderzuhängen. Wie das funktioniert weiß ich aber auch nur für strings.

    Kann mir da jemand nochmal kurz helfen?



  • Apeiron schrieb:

    Vielen Dank, nun funktioniert es prächtig.
    Aber warum ging es dann auch nicht als ich Port 123 verwendet habe?

    Nun habe ich noch ein Problem. Ich bekomme einen String aus Buchstaben. Ich habe vermutet, dass die Asci Codes der Buchstaben dann die Zeit ergeben. Aber wie wandle ich den String bloß in eine Zahl um? Atoi geht nicht da der String aus Buchstaben besteht. sscanf funktioniert auch nicht. Warum? Schließlich würde noch die Möglichkeit bleiben, die Einträge des arrays einzeln zu casten, (Wie man ein ganzes array castet weiß ich nicht) und dann die integers aneinaderzuhängen. Wie das funktioniert weiß ich aber auch nur für strings.

    Kann mir da jemand nochmal kurz helfen?

    Scheinbar hast Du in diesem Bereich nicht so viel Ahnung. Und vieles davon gehört zu den Grundlagen. Denn Code hast Du dir von Felix Opatz kopiert von http://www.zotteljedi.de/socket-tipps/ da würde ich mein Cluster darauf verwetten.

    Apeiron schrieb:

    Aber warum ging es dann auch nicht als ich Port 123 verwendet habe?

    Weil das ältere "Time Protocol" noch auf dem (standard) Port 37 erreichbar ist. Sowohl TCP als auch mit UDP! RFC 868 - Time Protocol

    Das neuere "Netwok Time Protocol" ist (standard) auf Port 123 (UDP) erreichbar. RFC - Network Time Protocol http://tools.ietf.org/html/rfc5905

    Dies ist aus RFC 868:
    [/quote]
    The server listens for a connection on port 37. When the connection is established, the server returns a 32-bit time value and closes the connection. If the server is unable to determine the time at its site, it should either refuse the connection or close it without sending anything.
    [quote="Apeiron"]

    Daher verstehe ich Deine 2te Frage überhaupt nicht. Zeig doch mal ein bisschen Code.

    RTFM



  • Nein, ich hab leider nicht viel Ahnung vom Thema. Hatte nur eine Einführungsvorlesung in C, da ist vieles zu kurz gekommen. Den Code habe ich mir woanders geholt. Ich bekomme aber leider nur 7Bytes in Form von nichtnumerischen Zeichen zurück. Der Code steht ja oben, oder willst du mir sagen, dass er falsch ist?



  • Apeiron schrieb:

    Nein, ich hab leider nicht viel Ahnung vom Thema. Hatte nur eine Einführungsvorlesung in C, da ist vieles zu kurz gekommen. Den Code habe ich mir woanders geholt. Ich bekomme aber leider nur 7Bytes in Form von nichtnumerischen Zeichen zurück. Der Code steht ja oben, oder willst du mir sagen, dass er falsch ist?

    Okey... ein Post weiter oben habe ich aus RFC 868 - Time Protocol zitiert in welcher Form die Daten ankommen.



  • Ja du hast geschrieben time value. 64 bits(8bytes) sollten schon angekommen sein,wenn man das Stringendzeichen dazunimmt. Aber ich weiß nichts über dieses Format, muss mich erst ein bisschen kundig machen.



  • Apeiron schrieb:

    Ja du hast geschrieben time value. 32 bits(8bytes) sollten schon angekommen sein,wenn man das Stringendzeichen dazunimmt. Aber ich weiß nichts über dieses Format, muss mich erst ein bisschen kundig machen.

    Wie viel Bytes sind 32Bit!? Das wären 4Bytes und nicht 8.
    Jetz musst Du mir nur sagen was du implementieren möchtst. Das Time-Protocol, oder das Network-Time-Protocol. Nur das Time-Protocol kannst Du (auch) über TCP ansprechen auf Port 37. Und das TP gibt Dir nur ein unsigned integer in (network byte order) zurück. Die Zeitstempel im Network-Time-Protocol sind 64 Bits lang. 32 Bits kodieren die Sekunden seit dem 1. Januar 1900 00:00:00 Uhr, weitere 32 Bits den Sekundenbruchteil.

    Konvertierungs Funktion von network to host order:
    http://msdn.microsoft.com/en-us/library/ms740069%28v=vs.85%29.aspx
    Den Rückgabewert mit zbsp. ctime() aus "time.h" in ein String konvertieren.



  • Du hast Recht, dachte für einen kurzen Moment ein Byte wären 4 Bit.Das ist mir ja bald selber eingefallen, dass es nicht stimmt(Hätte nur mit deinen Infos über TP übereingestimmt!!!) und ist mir furchtbar peinlich...aber ich hab so selten damit was zutun, dass ichs über die Zeit vergessen habe. Aber was ich weiß ist, dass ein char 1byte belegt und ich bekomme 7bytes bzw. 8bytes, wenn da noch ein Stringendzeichen ist, was ich aber nicht vermute, nachdem du das mit dem Integer gesagt hast. Das passt dann wohl eher zu NTP oder?

    Ich möchte beim TP bleiben.Mein Program ist ja auch für TCP konzipiert, wusste nur nicht, dass ich Port 123 nur mit UDP verwenden kann, Port 37 aber sowohl mit UDP als auch mit TCP.

    Bin ja nicht untätig gewesen, und habe versucht, schon das empfangende char array in eine int Variable oder ähnliches umzuwandeln, aber die Funktion

    int recv (
      SOCKET s,       
      char FAR* buf,  
      int len,        
      int flags       
    );
    

    verlangt nach diesem char array. Oder kennt jemand eine andere Funktion die dasselbe für eine unsigned int variable macht?

    Deshalb war es ja meine Vermutung, dass ich den integer den ich bekomme, durch das char array automatisch caste. Die Zeichen ändern sich ja auch dauernd mit der Zeit. Die Bitzahl stimmt ja. Ich wollte ja in den obigen Posts dauernd wissen wie ich den string zurück in einen Integer transformieren soll und habe auch schon einige eigene, nicht funktionierende Vorschläge gebracht. Könnte mir vlt.mal jemand ein paar konkrete Programmiertips geben? Danke!

    Für das Umwandeln von Network byte order in die normale Reihenfolge kenne ich die Funktion htons, aber deine Funktion scheint noch besser geeignet. Dafür brauche ich aber ja schon einen ganzzahligen Datentyp. Und mein Problem ist ja gerade, dass ich den nicht habe.

    ctime brauche ich nicht. Mir reicht die Zeit in Sekunden.

    Ich hoffe, mein eigentliches Problem ist nun besser klar geworden, denn bis jetzt hat mich die Diskussion hier leider nicht weitergebracht.



  • rtfm



  • Ich hab jetzt das Handbuch von diesem Zotteljedi gelesen. Du hattest Recht, ich bekomme 4byte, der Rest war Müll, wie ich auch am Rückgabewert von recv gesehen habe. Er hat aber auch geschrieben, dass Binärdaten meist ascii codiert ankommen.
    Könntest du mir zum. verraten, ob der Ansatz, die chars zu casten und als ints dann irgedwie zusammenzuhängen falsch ist?
    Hilf mir doch, wenn du dich auskennst....für dich ist es in diesem Fall doch leicht, du hast den Überblick.
    Ich habe es bis jetzt nur überflogen und nix gefunden, was mir wirklich hilft, aber vlt. sollte ich es nochmal lesen, wenn du dir so sicher bist, dass ich die Antwort darin finde.



  • Ehrlich gesagt ich weiss nicht was Du willst. Deine schilderungen stimmen nicht mit den Protokolen überein!

    memcpy(&wert ,array ,sizeof(wert) );
    

    So könnte man ein array mit 4 bytes in ein integer umwandeln.
    Und bei TP Protocol kommst Du nur 4bytes retour und nicht 8!
    Daher verstehe ich Dein durcheinader überhaupt nicht.

    Bitte informiere Dich über das Protocol TP, und wie man einen Client implementiert.
    http://www.faqs.org/rfcs/rfc868.html

    EDIT: sorry habe dein Post gerade gelesen...



  • Oke Danke! Ja das Durcheinander mit der Größe hat sich geregelt, wie du schon bemerkt hast. Es kommen definitiv 4bytes an. Sry mein Fehler!

    Oke in der Information steht nix drin, was ich nicht gemacht hätte. Es steht aber, dass die Daten als Binärzahl, also vom Typ int ankommen sollen. Tatsache ist aber, dass ich für recv ein char array brauche. Dann also eine Binärzahl in ein char array gespeichert werden müsste. Heißt das dann nicht, dass diese Zahl in eine Zeichenkette umgewandelt werden muss? Dank deinem Tip ist es mir nun gelungen, sie in einen unsigned long typ zurückzukonvertieren!

    Danke, danke für die Funktion!!! 👍 Genau das habe ich die ganze Zeit gesucht!!!!

    Mit diesem Code wird mir der realistische Wert von 3522505092 geliefert! Warum hast du mir die Funktion nicht gleich gegeben?

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <winsock2.h>
    
    int startWinsock(void)
    
    {
    
      WSADATA wsa;
    
      return WSAStartup(MAKEWORD(2,0),&wsa);
    
    }
    
    int startWinsock(void);
    
    int main(int argc, char *argv[])
    {
    
      long rc;
    
      SOCKET s;
    
      SOCKADDR_IN addr;
    
      char buf[4];
    
      unsigned long  zeit;  // Definiere Zeitvariable
    
      rc=startWinsock();
    
      if(rc!=0)
    
      {
    
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
    
        return 1;
    
      }
    
      else
    
      {
    
        printf("Winsock gestartet!\n");
    
      }
    
    s=socket(AF_INET,SOCK_STREAM,0);
    
    if(s==INVALID_SOCKET)
    
    {
    
      printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
    
      return 1;
    
    }
    
    else
    
    {
    
      printf("Socket erstellt!\n");
    
    }
    
    memset(&addr,0,sizeof(SOCKADDR_IN));
    
    addr.sin_family=AF_INET;
    
    addr.sin_port=htons(37); 
    
    addr.sin_addr.s_addr=inet_addr("192.53.103.108"); 
    
    rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
    
    if(rc==SOCKET_ERROR)
    
    {
    
      printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
    
    }
    
    else
    
    {
    
      printf("Verbunden mit 192.53.103.108 \n");
    
    }
    
    rc=recv(s,buf,4,0);
    
    printf("Anzahl der empfangenen Bytes: %d\n",rc);
    
    memcpy(&zeit ,buf ,sizeof(zeit) );
    
    zeit=ntohl(zeit);
    
    printf("%u\n",zeit);
    
    system("PAUSE");	
      return 0;
    }
    


  • Apeiron schrieb:

    Danke, danke für die Funktion!!! 👍 Genau das habe ich die ganze Zeit gesucht!!!!

    Mit diesem Code wird mir der realistische Wert von 3522505092 geliefert! Warum hast du mir die Funktion nicht gleich gegeben?

    Weil Du am Anfang ein völliges durcheinader hattest! Zuerst musst Du doch wissen wie das Protocol zu implementieren ist, und dann kannst Du agieren.
    Ok, schön das es jetzt funktioniert. Einen kleinen Fehler habe ich dennoch gesehen, und zwar bei der recv() Funktion. Denn Du kannst nicht davon ausgehen das Du auch auf ein Schlag alle 4 Bytes bekommst. Du musst den Rückgabewert von recv() prüfen und gegebenfals noch einmal in Empfang gehen bis alle Daten angekommen sind. Denn wenn Du dass nicht machst, bekommst du vieleicht einmal nur 2Bytes, und dann ist der timestamp dahin.

    recv()http://msdn.microsoft.com/en-us/library/ms740121%28v=vs.85%29.aspx


Anmelden zum Antworten