Monitoring-Programm / TCP oder UDP?
Monitoring-Programm / TCP oder UDP?
Hallo zusammen,
ich versuche mich grad an einem Monitoring-Programm. Der Client ist hierbei der Monitor der die Daten anzeigt, der Server liefert die Daten eines Rechners im Netzwerk. Die konstanten Daten wie z.B. Prozessorname, Anzahl der Kerne, usw. soll einmalig übertragen werden. Variable Daten, wie z.B. die CPU-Auslastung sollen alle paar Sekunden übertragen werden.
Ich habe mir gedacht, dass ich eine TCP-Verbindung ausgehend vom Client aufbaue. Der Server sendet mir daraufhin die konstanten Daten zurück. Die variablen Daten würde ich daraufhin per UDP automatisch per Timer gesteuert vom Server senden.
Meine Frage:
Ist es sinnvoll die variablen Daten per UDP zu senden? Oder könnte ich genausogut die TCP-Verbindung aufrecht erhalten und die Daten hierüber senden?
Gruß,
Wumpi
ich versuche mich grad an einem Monitoring-Programm. Der Client ist hierbei der Monitor der die Daten anzeigt, der Server liefert die Daten eines Rechners im Netzwerk. Die konstanten Daten wie z.B. Prozessorname, Anzahl der Kerne, usw. soll einmalig übertragen werden. Variable Daten, wie z.B. die CPU-Auslastung sollen alle paar Sekunden übertragen werden.
Ich habe mir gedacht, dass ich eine TCP-Verbindung ausgehend vom Client aufbaue. Der Server sendet mir daraufhin die konstanten Daten zurück. Die variablen Daten würde ich daraufhin per UDP automatisch per Timer gesteuert vom Server senden.
Meine Frage:
Ist es sinnvoll die variablen Daten per UDP zu senden? Oder könnte ich genausogut die TCP-Verbindung aufrecht erhalten und die Daten hierüber senden?
Gruß,
Wumpi
Generell:
UDP bietet sich an, wenn man die Flusskontrolle vom TCP nicht nutzen kann / will ...
Insbesondere, wenn man den Sendezeitpunkt von TCP nicht verzögern lassen moechte.
Wenn performance keine Rolle spielt, bzw TCP im bereich liegt, wuerd ich TCP nehmen, ganz einfach auch weil nen status der Verbindung hasst.
Manchen Admins stoesst es sicher auf, wenn fehlinformierte Programme ihre daten per UDP in die weite welt schicken, obwohl der empfaenger scho lange down ist
wenn du aller sek mal 400-500 byte schickst, wirst kaum nen unterschied merken, ausser im Programmieraufwand vielleicht
Ciao ...
UDP bietet sich an, wenn man die Flusskontrolle vom TCP nicht nutzen kann / will ...
Insbesondere, wenn man den Sendezeitpunkt von TCP nicht verzögern lassen moechte.
Wenn performance keine Rolle spielt, bzw TCP im bereich liegt, wuerd ich TCP nehmen, ganz einfach auch weil nen status der Verbindung hasst.
Manchen Admins stoesst es sicher auf, wenn fehlinformierte Programme ihre daten per UDP in die weite welt schicken, obwohl der empfaenger scho lange down ist
wenn du aller sek mal 400-500 byte schickst, wirst kaum nen unterschied merken, ausser im Programmieraufwand vielleicht
Ciao ...
Danke für die Erläuterungen
. Ich denke, dann sollte ich es mal mit TCP probieren. Habe mal ein kleines Beispiel, das ich aus einem Buch entnommen habe, leicht bearbeitet. Der Client initiiert eine TCP-Verbindung und der Server schickt daraufhin die CPU-Auslastung zurück. Es wäre nun schön, wenn ich den Server dazu bringen könnte, per QTimer alle paar Sekunden die Auslastung rüberzuschicken. Wäre das in meinem Beispielprogramm leicht zu realisieren?
Hier mal der relevante Code:
Client
Server
Gruß,
Wumpi
Hier mal der relevante Code:
Client
Code: Alles auswählen
client::client(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
//neuen TCP-Socket erstellen
mytcpsock = new QTcpSocket(this);
// Signal-Slot Verbindungen
connect(okButton, SIGNAL(clicked()), this, SLOT(requestData()));
connect(stopButton, SIGNAL(clicked()), this, SLOT(close()));
connect(mytcpsock, SIGNAL(readyRead()), this, SLOT(readData()));
connect(mytcpsock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
}
client::~client()
{
}
// Anforderung an den Server stellen
void client::requestData(){
blockSize = 0;
//falls in Verwendung, Socket zurücksetzen
mytcpsock->abort();
//mit dem Server verbinden
mytcpsock->connectToHost(QHostAddress::LocalHost, 12345);
}
// die Antwort des Servers lesen
void client::readData(){
QDataStream in(mytcpsock);
in.setVersion(QDataStream::Qt_4_0);
if(blockSize == 0){
// Sind Daten zum Lesen vorhanden
if(mytcpsock->bytesAvailable() < (int)sizeof(quint16))
return;
in >> blockSize;
}
if(mytcpsock->bytesAvailable() < blockSize)
return;
int load;
in >> load;
LcdNumber->display(int(load));
}
Code: Alles auswählen
Server::Server(QWidget *parent) : QDialog(parent){
// neuen TCP-Server erstellen
tcpServer = new QTcpServer(this);
// auf eingehende Verbindungen am Port lauschen
if(!tcpServer->listen(QHostAddress::Any, 12345)){
QMessageBox::critical(this,tr("Data-Server"),tr("Fehler beim Server: %1.").arg(tcpServer->errorString()));
//Server schliessen
close();
return;
}
statusLabel->setText(tr("Der Server läuft an Port %1\n und wartet auf Client-Anfragen").arg(tcpServer->serverPort()));
// Signal-Slot-Verbindungen einrichten
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
// bei neuer eingehender Client-Verbindung den Slot sendData() aufrufen
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendData()));
}
void Server::sendData(){
// die Daten werden als QByteArray gesendet
int load;
QTcpSocket *clientConnection;
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << quint16(0);
// Daten für den Client erstellen
load = getCpuLoad();
out << load;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
// Gibt die nächste Client-Verbindung (in der Warteschlange) zurück
clientConnection = tcpServer->nextPendingConnection();
// Signal für den Socket einrichten, dass der unnötig belegte Speicher
// auf der Serverseite beim Trennen der Verbindung bei Gelegenheit
// freigegeben wird. Der Slot deleteLater ist in QObject definiert.
connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
// die Daten (Zeit) in das Socket schreiben
clientConnection->write(block);
// nach getaner Arbeit den Client vom Host trennen
clientConnection->disconnectFromHost();
}
Gruß,
Wumpi
Zuletzt geändert von Wumpi am 31. März 2011 12:10, insgesamt 1-mal geändert.
Hallo zusammen,
das mit der TCP-Verbindung ist sogut wie gelöst. Ein Problem habe ich noch. Ich möchte einen Timer starten nachdem eine Methode ausgeführt wurde. Dieser Timer startet nach Ablauf die Methode erneut. Irgendwie hört sich es einfach an, aber ich steh grad auf dem Schlauch..
Habs mir so gedacht, wie im Code. Allerdings weiß ich nicht, wie ich den Timer starten kann.
Schön wäre sowas wie
connect(this, SIGNAL(sendbeendet()), mytimer, SLOT(start()));
Bekommt man das irgendwie hin?
Gruß
das mit der TCP-Verbindung ist sogut wie gelöst. Ein Problem habe ich noch. Ich möchte einen Timer starten nachdem eine Methode ausgeführt wurde. Dieser Timer startet nach Ablauf die Methode erneut. Irgendwie hört sich es einfach an, aber ich steh grad auf dem Schlauch..
Code: Alles auswählen
mytimer = new QTimer
mytimer->setInterval(2000);
mytimer->setSingleShot(1);
connect(mytimer, SIGNAL(timeout()), this, SLOT(send()));
void Server::send(){
...
...
...
}
Habs mir so gedacht, wie im Code. Allerdings weiß ich nicht, wie ich den Timer starten kann.
Schön wäre sowas wie
connect(this, SIGNAL(sendbeendet()), mytimer, SLOT(start()));
Bekommt man das irgendwie hin?
Gruß
Entweder ich versteh die Frage falsch oder die Antwort ist tatsächlich trivial:
selbstverständlich geht das:
oder auch mit Signal:
aber eben: evt. verstehe ich auch was falsch..
BTW:
das schreibt man in ordentlichem C++ so:
sonst ist das irreführend.
hth!
selbstverständlich geht das:
Code: Alles auswählen
void Server::send(){
...
...
mytimer->start();
} Code: Alles auswählen
void Server::send(){
...
...
emit sendbeendet();
} BTW:
Code: Alles auswählen
mytimer->setSingleShot(1); Code: Alles auswählen
mytimer->setSingleShot(true); hth!
Nein, die Möglichkeit hatte ich auch getestet. Führt bei mir zu einem Fehler -> Unbehandelte Ausnahme bei 0x77ad64f4....solarix hat geschrieben: selbstverständlich geht das:Code: Alles auswählen
void Server::send(){ ... ... mytimer->start(); }
Genau das hab ich gesucht. Funktioniert einwandfrei. Vielen Dank!solarix hat geschrieben: oder auch mit Signal:Code: Alles auswählen
void Server::send(){ ... ... emit sendbeendet(); }