QTcpSocket zwei-Wege-Kommunikation zwischen client und server
bin ich, eine app zu entwickeln für den Raspberry PI, basierend auf der socket-Schnittstelle. Die Grundidee ist, dass der Raspberry wird mit einem sensor verbunden, Daten sammeln und senden es per WiFi auf Android-Gerät. Von Android kann ich die Kommunikation mit sensor senden einiger Befehle. Ich bin ein Anfänger in dieser Art von Entwicklung und nach einigen tutorials über QTcpSocket habe ich eine einfache client-server-Anwendung, sondern es ist nur in eine Richtung. Server lauscht auf das, was client sendet. Könnten Sie mir helfen, es zu verbessern, in zwei-Wege-Kommunikation? Ich habe gelesen, dass QTcpSocket nicht erforderlich threading für diese Art von problem, aber ich fand keine Lösung.
Ich würde schätzen jede Hilfe!!!
server.cpp:
#include "server.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <cstdio>
#include <QtDebug>
Server::Server(QObject *parent) :
QObject(parent)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()),
this, SLOT(on_newConnection()));
}
void Server::listen()
{
server->listen(QHostAddress::Any, 5100);
}
void Server::on_newConnection()
{
socket = server->nextPendingConnection();
if(socket->state() == QTcpSocket::ConnectedState)
{
printf("New connection established.\n");
qDebug()<<socket->peerAddress();
}
connect(socket, SIGNAL(disconnected()),
this, SLOT(on_disconnected()));
connect(socket, SIGNAL(readyRead()),
this, SLOT(on_readyRead()));
}
void Server::on_readyRead()
{
while(socket->canReadLine())
{
QByteArray ba = socket->readLine();
if(strcmp(ba.constData(), "!exit\n") == 0)
{
socket->disconnectFromHost();
break;
}
printf(">> %s", ba.constData());
}
}
void Server::on_disconnected()
{
printf("Connection disconnected.\n");
disconnect(socket, SIGNAL(disconnected()));
disconnect(socket, SIGNAL(readyRead()));
socket->deleteLater();
}
client.cpp
#include "client.h"
#include <QTcpSocket>
#include <QHostAddress>
#include <cstdio>
Client::Client(QObject *parent) : QObject(parent)
{
socket = new QTcpSocket(this);
printf("try to connect.\n");
connect(socket, SIGNAL(connected()),
this, SLOT(on_connected()));
}
void Client::on_connected()
{
printf("Connection established.\n");
char buffer[1024];
forever
{
while(socket->canReadLine())
{
QByteArray ba = socket->readLine();
printf("from server: %s", ba.constData());
}
printf(">> ");
gets(buffer);
int len = strlen(buffer);
buffer[len] = '\n';
buffer[len+1] = '\0';
socket->write(buffer);
socket->flush();
}
}
void Client::connectToServer()
{
socket->connectToHost(QHostAddress::LocalHost, 5100);
}
InformationsquelleAutor Krzysztof Jackowski | 2013-06-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vom architektonischen Standpunkt aus definieren Sie, einige Kommunikationsregeln (message flow) zwischen Ihrem server und client-ersten.
Dann nur Lesen(schreiben) von(zu) Instanz der QTCPSocket nach definierten flow.
Können Sie zum Beispiel Lesen von Daten auf der server-Seite, schauen, was Sie Antworten sollte, und schreiben Sie Antworten auf die gleichen sockel, von dem Sie gelesen haben. Für line-orientierte Nachrichten (und nur für Sie) - code könnte wie folgt Aussehen:
Persönlich, ich würde zu bewegen parsing und senden von Antworten von on_readyRead () - slot zu blockieren zu vermeiden event-Schleife zu lange Zeit, aber da Sie ein Anfänger in Netzwerkprogrammierung wollte ich nur klären, was getan werden könnte, um die Implementierung von zwei-Wege-Kommunikation.
Weitere details können Sie sehen, http://qt-project.org/doc/qt-4.8/qtnetwork.html
Denken Sie daran zu prüfen, wenn die Nachricht vollständig angekommen ist auf client und server-Seite. Wenn Sie verwenden Ihr eigenes Protokoll (kein HTTP -, FTP-oder andere standardisierte) Sie können eine Nachricht hinzufügen Länge auf den Beginn der Nachricht.
Ihre app wird nicht aufhören, während der Wartezeit für readyRead () - signal. Wenn es einige ready-to-read-Daten in den socket sendet es ein signal, dann wird Ihr on_readyRead () - slot wird aufgerufen. Sie Lesen von Daten, senden der Antwort (oder auch nicht, wenn es nicht notwendig ist) und die Kontrolle geht zurück an main-event-loop, in Ihrer Anwendung verarbeiten können weitere Veranstaltungen. In QT gibt es einen "non-blocking" Verhalten.
ok, ich verstehe. Die Sache ist, dass ich brauche-server zum senden von Daten, und der Kunde sollte senden Sie nur gelegentlich. So kann ich nicht schreiben auf der server-Seite in on_readyRead () - Methode, denn es wird nur ausgeführt, wenn der client etwas senden. Die Frage ist, wo soll ich das schreiben von Daten auf server-Seite? Gibt es einen slot, die kann ich verwenden für dieses problem?
Gibt es keine sagen wir mal "generische" Lösung. Zunächst einmal hängt es davon ab, was Ihre Daten-provider. Im einfachen Fall Ihre server könnte ein Daten-Anbieter selbst. Dann würden Sie haben, um Speicher-socket erhalten Sie in on_newConnection () - slot, d.h. als ein Mitglied-server, implementieren, die das sammeln von Daten die Funktionalität und schreiben von Daten gespeichert Buchse. Bessere Lösung wären getrennte Daten-provider erbt von QObject. Könnte man implementieren von Kommunikation zwischen Ihnen über signal-slot-Modell.
Vielen Dank für Ihre Zeit und Hilfe! Ich denke, signal-slot-Modell für mich arbeiten.
InformationsquelleAutor undercover
Alles, was Sie tun müssen, ist zu schreiben/Lesen aus dem socket vom client oder server. Eine TCP-Verbindung ist bereits zwei-Wege-Verbindung.
Können Sie sein, dass einige Probleme mit Ihren
forever
Schleife inClient
. Sie sollten wirklich diereadyRead
signal auf die Buchse in der gleichen Weise, dass Sie für den server und die Tropfen, dieforever
Schleife.Verarbeitung von Tastatureingaben in einer nicht blockierenden Weise, anstatt mit
gets()
.gets()
blockiert den main thread und verhindern, dass es bei der Ausführung der event-Schleife. Dies ist nicht der beste Weg, um Dinge zu handhaben, in Ihrem Fall, da Sie in der Lage sein zu handhaben, die Daten vom server und vom Benutzer zur gleichen Zeit.Vielleicht nehmen Sie einen Blick auf diese mit Bezug auf handling der Tastatur von einer console app:
mit-qtextstream-zu-Lesen-stdin-in-a-non-blocking-Mode
Alternativ machen Sie es eine GUI-app und verwenden Sie eine
QPlainTextEdit
.InformationsquelleAutor Pete