Ich habe es hinbekommen das der Client sich auf ein Server connected und sogar Daten zum Server schickt. Der Server stellt diese Daten auch erfolgreich dar.
Jetzt möchte ich jedoch auch vom Server zu genau dem Client eine Information (nur Text) schicken.
Also eine Kommunikation in beide Richtung (aber erst nachdem die ersten Infos vom Client zum Server gekommen sind)
Ziel der ganzen Programmierung ist ein Teamviewer fähiges Programm.
Das senden von Daten (Screenshot): Client -> Server habe ich wie oben geschrieben erfolgreich hinbekommen.
Jetzt fehlt nur noch das senden von Daten (Mausposition) zu genau diesen einem verbundenen Client: Server -> Client
Hat jemand für mich ein Tipp oder schon mal von solchen Programmierbeispielen gehört ?
Client Server Kommunikation (beidseitig)
Client Server Kommunikation (beidseitig)
Technik muss dem Menschen dienen, nicht umgekehrt
Re: Client Server Kommunikation (beidseitig)
Der Server hat für den Client ein entsprechenden Socket offen, d.h. über den Socket kannst Du vom Server auch Daten zum Client schicken.
Re: Client Server Kommunikation (beidseitig)
Ok ich habe es versucht und bin gescheitert
mysendImage.h
mysendImage.cpp
Serverseitig
libimageserver.h
libimageserver.cpp
Also so bekomme ich wunderbar das Bild(Serverseitig) und kann es in meiner aufrufenden Anwendung anzeigen.
Auf dem Server aber schreibe ich: in der Methode: "void ImageServer::removeConnection(){"
Mit diesem Aufruf habe ich jetzt erwartet das Clientseitig "void SendImage::ReadData(){" aufgerufen wird und mit:
mein Text vom Server ausgegeben wird. Dies passiert jedoch nicht nicht einmal die qDebug<<"ReadData"; wird ausgegeben, als ob er nicht einmal den Slot "ReadData()" ausrufen würde.
Oder habe ich prinz. ein Denkfehler ?
mysendImage.h
Code: Alles auswählen
#ifndef SENDIMAGE_H
#define SENDIMAGE_H
// QT
#include <QString>
#include <QTcpSocket>
#include <QImage>
#include <QTimer>
#include <QPixmap>
#include <QDesktopWidget>
#include <QApplication>
#include <QtGui/QWidget>
#include <QMainWindow>
#include <QScreen>
#include <QFile>
#include <QDateTime>
#include <QPainter>
#include <QMessageBox>
class SendImage : public QObject{
Q_OBJECT
public:
explicit SendImage(QString address, int port);
void send(QImage image, QString name);
void SendData(QString data);
private slots:
void setConnected();
void sendscreen();
void akt_status(QAbstractSocket::SocketState);
void hostFoundComplete();
void test(QAbstractSocket::SocketError socketError);
void ReadData();
void connected();
private:
void toggleConnection();
void reallySend(QString name, QImage image);
public:
QString name;
QString name_screen;
QImage image;
QImage image_screen;
QString address;
int port;
QTcpSocket* socket;
};
#endif // SENDIMAGE_H
Code: Alles auswählen
#include "mysendimage.h"
#include <QBuffer>
SendImage::SendImage(QString address, int port){
this->address = address;
this->port = port;
socket = new QTcpSocket(this);
connect(socket, SIGNAL(connected()), SLOT(setConnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(ReadData()));
this->sendscreen();
//SELF
// QTimer *support_Timer = new QTimer(this);
// support_Timer->setInterval(1000);
// support_Timer->start();
// qDebug()<<"Timer :)";
// connect(support_Timer, SIGNAL(timeout()), this, SLOT(sendscreen()));
}
void SendImage::setConnected(){
qDebug()<<"Connected with Server";
reallySend(this->name, this->image);
}
void SendImage::sendscreen(){
qDebug()<<"sendscreen";
QPixmap originalPixmap;
originalPixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
QPainter maus(&originalPixmap);
QPen stift(Qt::black);
stift.setWidth(10);
maus.setPen(stift);
maus.drawEllipse(QCursor::pos().x(),QCursor::pos().y(),20,20);
image_screen = originalPixmap.toImage().convertToFormat(QImage::Format_MonoLSB,Qt::MonoOnly);
name_screen = QString("Screen_%1.png").arg(QDateTime::currentDateTime().toString("dd_MM_yyyy-hh_mm_ss"));
this->send(this->image_screen,this->name_screen);
}
void SendImage::send(QImage image, QString name){
this->name = name; // Store the data
this->image = image; //
toggleConnection(); // Start connection
}
void SendImage::reallySend(QString name, QImage image){
qDebug()<<"Send Image with Name";
if(socket->state() == QAbstractSocket::ConnectedState){
qDebug()<<"echtes senden";
image.setText("name", name);
QByteArray ba;
QBuffer buffer(&ba);
image.save(&buffer, "PNG");
socket->write(ba);
}else{
qDebug("Image has not been send. No connection established!");
}
toggleConnection();
}
void SendImage::toggleConnection(){
if(socket->state() == QAbstractSocket::UnconnectedState){
socket->connectToHost(this->address, this->port, QIODevice::WriteOnly);
qDebug()<<"toggleConnection -> : "<<socket->state();
}else{
qDebug()<<"toggleConnection disconnectFromHost()";
socket->disconnectFromHost();
}
}
void SendImage::ReadData(){
qDebug()<<"ReadData";
while(socket->canReadLine()){
QString line = QString::fromUtf8(socket->readLine()).trimmed();
qDebug() << line;
}
}
libimageserver.h
Code: Alles auswählen
#ifndef IMAGESERVER_H
#define IMAGESERVER_H
#include <QTcpServer>
#include <QList>
#include <QHash>
class QBuffer;
class QTcpSocket;
class ImageServer : public QTcpServer{
Q_OBJECT
public:
ImageServer(QObject* parent = 0);
void setImagePath(QString path);
signals:
void newImage(QString filename);
private slots:
void addConnection();
void removeConnection();
void receiveImage();
private:
QString path;
QList<QTcpSocket*> connections;
QHash<QTcpSocket*, QBuffer*> buffers;
QTcpSocket *connection;
};
#endif // IMAGESERVER_H
Code: Alles auswählen
#include "libimageserver.h"
#include <QBuffer>
#include <QTcpSocket>
#include <QImage>
#include <QDebug>
ImageServer::ImageServer(QObject* parent) : QTcpServer(parent){
connect(this, SIGNAL(newConnection()), this, SLOT(addConnection()));
path = "";
}
void ImageServer::setImagePath(QString path){
this->path = path;
}
void ImageServer::addConnection(){
qDebug("Adding connection");
connection = nextPendingConnection();
connections.append(connection);
QBuffer* buffer = new QBuffer(this);
buffer->open(QIODevice::ReadWrite);
buffers.insert(connection, buffer);
connect(connection, SIGNAL(disconnected()), SLOT(removeConnection()));
}
void ImageServer::removeConnection(){
qDebug("Remove connection");
receiveImage();
connection->write(QString("test vom Server\n").toUtf8());
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.take(socket);
buffer->close();
buffer->deleteLater();
connections.removeAll(socket);
socket->deleteLater();
}
void ImageServer::receiveImage(){
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.value(socket);
// missing some checks for returns values for the sake of simplicity
qint64 bytes = buffer->write(socket->readAll());
// go back as many bytes as we just wrote so that it can be read
buffer->seek(buffer->pos() - bytes);
QImage image;
image.loadFromData(buffer->buffer());
if(image.isNull())
qDebug("The image is null. Something failed.");
QString filename = path + "\\" + image.text("name");
image.save(filename);
qDebug("image received");
emit newImage(filename);
}
Auf dem Server aber schreibe ich:
Code: Alles auswählen
...
connection->write(QString("test vom Server\n").toUtf8());
...
Mit diesem Aufruf habe ich jetzt erwartet das Clientseitig "void SendImage::ReadData(){" aufgerufen wird und mit:
Code: Alles auswählen
qDebug()<<"ReadData";
while(socket->canReadLine()){
QString line = QString::fromUtf8(socket->readLine()).trimmed();
qDebug() << line;
}
Oder habe ich prinz. ein Denkfehler ?
Technik muss dem Menschen dienen, nicht umgekehrt
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Re: Client Server Kommunikation (beidseitig)
Du versuchst Daten zu schicken in dem Slot in dem Du auf das disconnected() - Signal reagierst? Wie sollte man noch was schicken können wenn der Socket disconnected ist?
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Re: Client Server Kommunikation (beidseitig)
Habe gedacht es ist wie der Destruktor zu verstehen.
Wollte darin den Verbindungsabbau steuern
bzw. meine Nachricht noch abschicken 
Habe nun:
H.d. das "zurückschreiben" an den Client in newConnection drin. Jedoch zerstöre ich mir damit jetzt das Bild.
Gibt es evtl. die Möglichkeit Clientseitig auf eine Methode vom Server zuzugreifen. Wie ein Funktionsaufruf(Methodenaufruf) in einem Objekt ?
Wollte darin den Verbindungsabbau steuern
Habe nun:
Code: Alles auswählen
void ImageServer::addConnection(){
qDebug("Adding connection");
connection = nextPendingConnection();
connections.append(connection);
QBuffer* buffer = new QBuffer(this);
buffer->open(QIODevice::ReadWrite);
buffers.insert(connection, buffer);
connection->write(QString("test vom Server\n").toUtf8());
connect(connection, SIGNAL(disconnected()), SLOT(removeConnection()));
}
Gibt es evtl. die Möglichkeit Clientseitig auf eine Methode vom Server zuzugreifen. Wie ein Funktionsaufruf(Methodenaufruf) in einem Objekt ?
Technik muss dem Menschen dienen, nicht umgekehrt
Re: Client Server Kommunikation (beidseitig)
Kann mir da noch jemand ein Tipp geben ? Wie bekomme ich doch noch den Client vom Server aus angesprochen ?
Technik muss dem Menschen dienen, nicht umgekehrt