Oh... an "urgent" thread, lol
I have one question for you - why are you using QDataStream? Not that you actually send some data to it but you do realize no NTP server will know how to deserialize data serialized with QDataStream, right?
Oh... an "urgent" thread, lol
I have one question for you - why are you using QDataStream? Not that you actually send some data to it but you do realize no NTP server will know how to deserialize data serialized with QDataStream, right?
Just a quick test using netcat against my NTP server shows that the intent of AtomicClock::connectSuccsess(), which is sending a stream of 48 '0' characters to the server (did you mean NUL characters?), does not elicit a response. Perhaps you need to send a well-formed NTP request to the server?
I would suggest getting a hold of the NTP server code from ntp.org and looking at the source to the bundled ntpdate program.
Hello,
to fatjuicymole, i know that i have just written that after i couldnt make work with this small code about 3 days, its just feeiling and wish..
second, i have checked the server with windows ntp client and few other free programs too, it works and the server address i use is a free organization server ntp.org. actually i used my code for other servers too so same problem occurs again.
to wysota, I dindnt think in that way, i try to write just a client program, i need to use QByteArray for time request. It is the same way the other codes do same jobb.. no way tried without datastream, and tried with connectToHost, write, read does not call readPendingDatagrams() anyway.
to ChrisW67, yeah i ment to send null characters with 48 length.
So 4 zeros or 4 null characters?
Qt Code:
To copy to clipboard, switch view to plain text mode
I would like to be a "Guru"
Useful hints (try them before asking):
- Use Qt Assistant
- Search the forum
If you haven't found solution yet then create new topic with smart question.
use of flush() makes no difference, i mean char '0', saw that in a c# example..
RFC 1305 Section 3 and Appendix A. The packet format is substantially more complex than an 48-byte block of zero bytes. This is a request and response on my machine.
Qt Code:
Frame 1 (90 bytes on wire, 90 bytes captured) Ethernet II, Src: 192.168.1.6 (00:1a:4d:70:61:9c), Dst: CameoCom_c1:3e:76 (00:40:f4:c1:3e:76) Internet Protocol, Src: 192.168.1.6 (192.168.1.6), Dst: 192.168.1.1 (192.168.1.1) User Datagram Protocol, Src Port: 53531 (53531), Dst Port: ntp (123) Network Time Protocol Flags: 0xe3 11.. .... = Leap Indicator: alarm condition (clock not synchronized) (3) ..10 0... = Version number: NTP Version 4 (4) .... .011 = Mode: client (3) Peer Clock Stratum: unspecified or unavailable (0) Peer Polling Interval: 4 (16 sec) Peer Clock Precision: 0.015625 sec Root Delay: 1.0000 sec Root Dispersion: 1.0000 sec Reference Clock ID: NULL Reference Clock Update Time: NULL Originate Time Stamp: NULL Receive Time Stamp: NULL Transmit Time Stamp: Apr 2, 2010 02:12:51.5572 UTC 0000 00 40 f4 c1 3e 76 00 1a 4d 70 61 9c 08 00 45 00 .@..>v..Mpa...E. 0010 00 4c 00 00 40 00 40 11 b7 49 c0 a8 01 06 c0 a8 .L..@.@..I...... 0020 01 01 d1 1b 00 7b 00 38 83 a1 e3 00 04 fa 00 01 .....{.8........ 0030 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0050 00 00 cf 5f d1 23 8e a1 83 72 ..._.#...r No. Time Source Destination Protocol Info 2 0.000254 192.168.1.1 192.168.1.6 NTP NTP server Frame 2 (90 bytes on wire, 90 bytes captured) Ethernet II, Src: CameoCom_c1:3e:76 (00:40:f4:c1:3e:76), Dst: 192.168.1.6 (00:1a:4d:70:61:9c) Internet Protocol, Src: 192.168.1.1 (192.168.1.1), Dst: 192.168.1.6 (192.168.1.6) User Datagram Protocol, Src Port: ntp (123), Dst Port: 53531 (53531) Network Time Protocol Flags: 0x24 00.. .... = Leap Indicator: no warning (0) ..10 0... = Version number: NTP Version 4 (4) .... .100 = Mode: server (4) Peer Clock Stratum: secondary reference (3) Peer Polling Interval: 4 (16 sec) Peer Clock Precision: 0.000001 sec Root Delay: 0.0388 sec Root Dispersion: 0.1307 sec Reference Clock ID: 192.231.203.132 Reference Clock Update Time: Apr 2, 2010 02:05:40.4534 UTC Originate Time Stamp: Apr 2, 2010 02:12:51.5572 UTC Receive Time Stamp: Apr 2, 2010 02:12:51.5165 UTC Transmit Time Stamp: Apr 2, 2010 02:12:51.5165 UTC 0000 00 1a 4d 70 61 9c 00 40 f4 c1 3e 76 08 00 45 00 ..Mpa..@..>v..E. 0010 00 4c 00 00 40 00 40 11 b7 49 c0 a8 01 01 c0 a8 .L..@.@..I...... 0020 01 06 00 7b d1 1b 00 38 82 6e 24 03 04 ec 00 00 ...{...8.n$..... 0030 09 ef 00 00 21 73 c0 e7 cb 84 cf 5f cf 74 74 10 ....!s....._.tt. 0040 e8 71 cf 5f d1 23 8e a1 83 72 cf 5f d1 23 84 38 .q._.#...r._.#.8 0050 8d a6 cf 5f d1 23 84 3b c2 52 ..._.#.;.RTo copy to clipboard, switch view to plain text mode
In the request the first UDP payload byte is the "e3" on line 23 of the listing.
thanks to everyone, now it is one step ahead. the code works as a client and retrieves server response. i used wireshark(it didnt like wireless but got the frames with cable connection) to examine the client and server packets, i used my code and an SNTPClient Solution from DaveyM69, the problem was the udp request(as many of you mentioned), i used very stupid(because its not complex) way to code my request. its shown below, now the problem is to get the data(i couldnt read it or show it, dont know why)..
Qt Code:
void AtomicClock::connectSuccsess() { ui->time->setText("Connected"); timeRequest[0] = 0x23; //Obs! first byte, important, makes a ntp client version 4, lazy way //the rest of the btes sends null, it means very wrong timestamps, but i dont need them now..just get the //time from server. udpSocket->write(timeRequest); }To copy to clipboard, switch view to plain text mode
the second part which is stll not working properly..
Qt Code:
void AtomicClock::readPendingDatagrams() { ui->statusLabel->setText("Reading..."); QByteArray newTime; do { newTime.resize(udpSocket->pendingDatagramSize()); udpSocket->read(newTime.data(), newTime.size()); } while(udpSocket->hasPendingDatagrams()); QString dateTime; in >> dateTime; ui->textEdit->setText(dateTime); }To copy to clipboard, switch view to plain text mode
Last edited by wysota; 3rd April 2010 at 09:05.
You are not getting a response because there's insufficient information in the request you are sending. The minimum that seems to elicit a response from my NTP server is (hex):
The first ten bytes have values. (nc is the netcat utility)Qt Code:
echo -ne "\xe3\x00\x04\xfa\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | nc -u ptolemy 123 | od -tx1 0000000 24 03 04 ec 00 00 09 ac 00 00 28 4a c0 e7 cb 84 0000020 cf 61 03 93 73 5d d6 6e 00 00 00 00 00 00 00 00 0000040 cf 61 09 af 61 26 62 2c cf 61 09 af 61 29 fa 5eTo copy to clipboard, switch view to plain text mode
You still need to disassemble the 64-bit time stamp into something that you can use as a time.
Hi, I managed to get response from the ntp server, if you just see my code up there. now the problem is to get the transmit timestamp or read it in a proper way to get the time UTC 1.1.1970 + seconds.. I changed my readPendingDatagrams() function..but it gives ugly reply if i run the code. Can i get little bit help for that? i am just conderned wtih last 8 bytes(transmit stamp)..thanks.
Qt Code:
void AtomicClock::readPendingDatagrams() { ui->statusLabel->setText("Reading..."); QByteArray newTime; do { newTime.resize(udpSocket->pendingDatagramSize()); udpSocket->read(newTime.data(), newTime.size()); } while(udpSocket->hasPendingDatagrams()); QByteArray TransmitTimeStamp ; TransmitTimeStamp = newTime.right(8); quint64 seconds = 0; for (int i=0; i<= 3; i++) { seconds = (seconds << 8) | TransmitTimeStamp[i]; } quint64 fractions = 0; for (int i=4; i<= 7; i++) { fractions = (fractions << 8) | TransmitTimeStamp[i]; } double ticks = seconds + (fractions / 0x100000000L); //QDateTime newestTime = Epoch + ticks;To copy to clipboard, switch view to plain text mode
yes, got it! even i cant call that code perfect, it works, sends ntp client request ver. 4 to server on udp port 123 and gets server response 48 bytes, after that TransmitTimeStamp is choosen from the bytearray last (8 bytes), actually i used just the seconds the first 4 bytes but not last 4 bytes(fraction) dont need to be very sensitive within this prog. code includes some labels and texedit objects, the purpose is just to see on gui how the code would run.. i copy my code here, so maybe someone needs in the future. thanks eveyone on this thread..got much help with wireshark, and ntp request advices..
Qt Code:
#ifndef ATOMICCLOCK_H #define ATOMICCLOCK_H #include <QMainWindow> #include <QAbstractSocket> #include <QUdpSocket> #include <QHostInfo> #include <QHostAddress> #include <QDateTime> namespace Ui { class AtomicClock; } Q_OBJECT public: ~AtomicClock(); protected: private: Ui::AtomicClock *ui; QUdpSocket *udpSocket; private slots: void on_TimeUpdate_clicked(); void readPendingDatagrams(); void connectSuccsess(); }; #endif // ATOMICCLOCK_HTo copy to clipboard, switch view to plain text mode
Qt Code:
#include "atomicclock.h" #include "ui_atomicclock.h" ui(new Ui::AtomicClock) { ui->setupUi(this); } AtomicClock::~AtomicClock() { delete ui; udpSocket->close(); } { switch (e->type()) { ui->retranslateUi(this); break; default: break; } } void AtomicClock::on_TimeUpdate_clicked() { ui->ipAddress->setText(ipAddress); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); connect(udpSocket, SIGNAL(connected()), this, SLOT(connectSuccsess())); udpSocket->abort(); udpSocket->connectToHost("0.pool.ntp.org", 123); } void AtomicClock::readPendingDatagrams() { ui->statusLabel->setText("Reading..."); QByteArray newTime; do { newTime.resize(udpSocket->pendingDatagramSize()); udpSocket->read(newTime.data(), newTime.size()); } while(udpSocket->hasPendingDatagrams()); QByteArray TransmitTimeStamp ; TransmitTimeStamp = newTime.right(8); quint64 seconds = 0; for (int i=0; i<= 3; ++i) { seconds = (seconds << 8) | TransmitTimeStamp[i]; } QDateTime newestTime; newestTime.setTime_t(seconds - Epoch.secsTo(unixStart)); ui->textEdit->append(newestTime.toString()); } void AtomicClock::connectSuccsess() { ui->time->setText("Connected"); timeRequest[0] = '\x23'; udpSocket->flush(); udpSocket->write(timeRequest); }To copy to clipboard, switch view to plain text mode
hi again,
the code over there sometimes does not work, do you know why? i need to make it correct, nedd help of you , guys!
can not get (or calculate wrong) correct time from server..
thanks in advance
Qt Code:
# void AtomicClock::readPendingDatagrams() # { # ui->statusLabel->setText("Reading..."); # QByteArray newTime; # # # do { # newTime.resize(udpSocket->pendingDatagramSize()); # udpSocket->read(newTime.data(), newTime.size()); # } while(udpSocket->hasPendingDatagrams()); # # QByteArray TransmitTimeStamp ; # TransmitTimeStamp = newTime.right(8); # # quint64 seconds = 0; # for (int i=0; i<= 3; ++i) # { # seconds = (seconds << 8) | TransmitTimeStamp[i]; # } # # # QDateTime newestTime; # newestTime.setTime_t(seconds - Epoch.secsTo(unixStart)); # ui->textEdit->append(newestTime.toString());To copy to clipboard, switch view to plain text mode
Bookmarks