crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Обмен данными между сервером и клиентом.
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
fizmatovec Дата 11.11.2010, 1:19
  Здравствуйте. Пишу программу клиент-сервер(два в одном),т.е. хочу обмениваться сообщениями по сети. Запускаю на разных компах, соединение устанавливается, приходит ответ от сервера. Но вот посланное мною сообщение не доходит...Помогите,пожалуйста,разобраться что я делаю не так??
Вот код: (файл .h)
Раскрывающийся текст

#
ifndef SERVERCLIENT_H
#define SERVERCLIENT_H

#include <QtGui>
class QTcpServer;
class QTcpSocket;

class Widget :public QWidget{
    Q_OBJECT
    public:
    QPushButton* connection;
    QPushButton* opendir;
    QPushButton* send;
    QLabel* label_port;
    QLabel* label_answer;
    QLineEdit* IP;
    QLineEdit* Port;
    QLineEdit* letter;
    QTcpServer* TcpServer;
    QTcpSocket* TcpSocket;
    QTextEdit* Chat;
    quint16 blockSize;
    Widget();
    public slots:
              void connection_clicked();
              void send_clicked();
              void opendir_clicked();
      virtual void slotNewConnection();
              void slotReadAnswer();

   protected:
              void sendAnswerToClient(QString& str);
              void send_letter_to_client();
};




#endif // SERVERCLIENT_H



Файл .cpp:
Раскрывающийся текст

#include "server-client.h"
#include <QDebug>
#include <QFileDialog>
#include <QtNetwork>


Widget::Widget(){
    // кнопка соединения
    connection = new QPushButton(QString("connection"),this);
    QObject::connect(connection,SIGNAL(clicked()),SLOT(connection_clicked()));
    // кнопка отпраки данных
    send = new QPushButton(QString("send"),this);
    QObject::connect(send,SIGNAL(clicked()),SLOT(send_clicked()));
    // кнопка выбора файла
    opendir = new QPushButton(QString("open dir"),this);
    QObject::connect(opendir,SIGNAL(clicked()),SLOT(opendir_clicked()));
    // Label port
    label_port = new QLabel(this);
    label_port->setText("Current Port");
    // Label answer
    label_answer = new QLabel(this);
    label_answer->setText(QString::fromLocal8Bit("Ждём ответа..."));
    // IP
    IP = new QLineEdit(this);
    IP->setText("IP");
    // Port
    Port = new QLineEdit(this);
    Port->setText("Port");
    // Letter
    letter = new QLineEdit(this);
    letter->setText("Enter message");
    Chat = new QTextEdit (this);
    // размещение виджетов
    QGridLayout *Layout = new QGridLayout;
    Layout->addWidget(IP,0,0);
    Layout->addWidget(Port,1,0);
    Layout->addWidget(letter,2,0);
    Layout->addWidget(label_port,3,0);
    Layout->addWidget(label_answer,4,0);
    Layout->addWidget(connection,0,1);
    Layout->addWidget(send,1,1);
    Layout->addWidget(opendir,2,1);
    Layout->addWidget(Chat,5,0);
    setLayout(Layout);
}


void Widget::connection_clicked(){  //настраиваем сервер на слушание каналов
  TcpServer = new QTcpServer(this);
    if (!TcpServer->listen(QHostAddress::Any,1115)) {
        QMessageBox::critical(this, tr("Server"),
                              tr("Unable to start the server: %1.")
                              .arg(TcpServer->errorString()));
        close();
        return;
    }
    label_port->setText(tr("port %1.\n").arg(TcpServer->serverPort()));  // Выводим порт сервера, если сервер прослушивает соединения, в противном случае выведется 0.
    QObject::connect(TcpServer,SIGNAL(newConnection()),SLOT(slotNewConnection())); // устанавливаем соединение с новым клиентом,который подключился
}

void Widget::send_clicked(){
    TcpSocket = new QTcpSocket(this);
    blockSize = 0;
    TcpSocket->connectToHost(IP->text(),1115);
    send_letter_to_client();
    QObject::connect(TcpSocket, SIGNAL(readyRead()), this, SLOT(slotReadAnswer()));  // читаем ответ сервера
   // посылаем клиенту сообщение
}

void Widget::opendir_clicked(){
  QFileDialog d;
  QString dir_name = d.getExistingDirectory();
}

void Widget::slotNewConnection(){  // создание нового соединения с очередным клиентом
  QString answer="Connected!!!";
  TcpSocket = TcpServer->nextPendingConnection();
  QObject::connect(TcpSocket,SIGNAL(disconnected()),TcpSocket,SLOT(deleteLater()))
;
  // читаем сообщение клиента,если он что-то нам сообщает
  QObject::connect(TcpSocket, SIGNAL(readyRead()),this,SLOT(slotReadAnswer()));
  sendAnswerToClient(answer);  // отсылаем ответ клиенту
}

void Widget::sendAnswerToClient(QString &str){ // отсылаем сообщение очередному клиенту об успешном соединении
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (quint16)0;
    out << str;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
    TcpSocket->write(block);
}

void Widget::slotReadAnswer(){
    TcpSocket = (QTcpSocket*)sender();
    QString str;
    QDataStream in(TcpSocket);
    in.setVersion(QDataStream::Qt_4_5);
    for (;;) {
        if (!blockSize) {
            if (TcpSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> blockSize;
        }

        if (TcpSocket->bytesAvailable() < blockSize) {
            break;
        }
        in >> str;
        blockSize = 0;
        Chat->append(str);
    }
  label_answer->setText(str);
}

void Widget::send_letter_to_client(){
    TcpSocket = new QTcpSocket(this);
    QString str;
    str = letter->text();
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (quint16)0;
    out << str;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
    TcpSocket->write(block);
}




Ещё заметил странную вещь. Беру пример из книги Макса Шлее, Server, с моей программы на неё приходят сообщения, а вот на мою никак не доходят...


Здравствуйте. Пишу программу клиент-сервер(два в одном),т.е. хочу обмениваться сообщениями по сети. Запускаю на разных компах, соединение устанавливается, приходит ответ от сервера. Но вот посланное мною сообщение не доходит...Помогите,пожалуйста,разобраться что я делаю не так??
Вот код: (файл .h)
Раскрывающийся текст

#ifndef SERVERCLIENT_H
#define SERVERCLIENT_H

#include <QtGui>
class QTcpServer;
class QTcpSocket;

class Widget :public QWidget{
    Q_OBJECT
    public:
    QPushButton* connection;
    QPushButton* opendir;
    QPushButton* send;
    QLabel* label_port;
    QLabel* label_answer;
    QLineEdit* IP;
    QLineEdit* Port;
    QLineEdit* letter;
    QTcpServer* TcpServer;
    QTcpSocket* TcpSocket;
    QTextEdit* Chat;
    quint16 blockSize;
    Widget();
    public slots:
              void connection_clicked();
              void send_clicked();
              void opendir_clicked();
      virtual void slotNewConnection();
              void slotReadAnswer();

   protected:
              void sendAnswerToClient(QString& str);
              void send_letter_to_client();
};




#endif // SERVERCLIENT_H



Файл .cpp:
Раскрывающийся текст

#include "server-client.h"
#include <QDebug>
#include <QFileDialog>
#include <QtNetwork>


Widget::Widget(){
    // кнопка соединения
    connection = new QPushButton(QString("connection"),this);
    QObject::connect(connection,SIGNAL(clicked()),SLOT(connection_clicked()));
    // кнопка отпраки данных
    send = new QPushButton(QString("send"),this);
    QObject::connect(send,SIGNAL(clicked()),SLOT(send_clicked()));
    // кнопка выбора файла
    opendir = new QPushButton(QString("open dir"),this);
    QObject::connect(opendir,SIGNAL(clicked()),SLOT(opendir_clicked()));
    // Label port
    label_port = new QLabel(this);
    label_port->setText("Current Port");
    // Label answer
    label_answer = new QLabel(this);
    label_answer->setText(QString::fromLocal8Bit("Ждём ответа..."));
    // IP
    IP = new QLineEdit(this);
    IP->setText("IP");
    // Port
    Port = new QLineEdit(this);
    Port->setText("Port");
    // Letter
    letter = new QLineEdit(this);
    letter->setText("Enter message");
    Chat = new QTextEdit (this);
    // размещение виджетов
    QGridLayout *Layout = new QGridLayout;
    Layout->addWidget(IP,0,0);
    Layout->addWidget(Port,1,0);
    Layout->addWidget(letter,2,0);
    Layout->addWidget(label_port,3,0);
    Layout->addWidget(label_answer,4,0);
    Layout->addWidget(connection,0,1);
    Layout->addWidget(send,1,1);
    Layout->addWidget(opendir,2,1);
    Layout->addWidget(Chat,5,0);
    setLayout(Layout);
}


void Widget::connection_clicked(){  //настраиваем сервер на слушание каналов
  TcpServer = new QTcpServer(this);
    if (!TcpServer->listen(QHostAddress::Any,1115)) {
        QMessageBox::critical(this, tr("Server"),
                              tr("Unable to start the server: %1.")
                              .arg(TcpServer->errorString()));
        close();
        return;
    }
    label_port->setText(tr("port %1.\n").arg(TcpServer->serverPort()));  // Выводим порт сервера, если сервер прослушивает соединения, в противном случае выведется 0.
    QObject::connect(TcpServer,SIGNAL(newConnection()),SLOT(slotNewConnection())); // устанавливаем соединение с новым клиентом,который подключился
}

void Widget::send_clicked(){
    TcpSocket = new QTcpSocket(this);
    blockSize = 0;
    TcpSocket->connectToHost(IP->text(),1115);
    // посылаем клиенту сообщение
    send_letter_to_client();
    QObject::connect(TcpSocket, SIGNAL(readyRead()), this, SLOT(slotReadAnswer()));  // читаем ответ сервера
  
}

void Widget::opendir_clicked(){
  QFileDialog d;
  QString dir_name = d.getExistingDirectory();
}

void Widget::slotNewConnection(){  // создание нового соединения с очередным клиентом
  QString answer="Connected!!!";
  TcpSocket = TcpServer->nextPendingConnection();
  QObject::connect(TcpSocket,SIGNAL(disconnected()),TcpSocket,SLOT(deleteLater()))
;
  // читаем сообщение клиента,если он что-то нам сообщает
  QObject::connect(TcpSocket, SIGNAL(readyRead()),this,SLOT(slotReadAnswer()));
  sendAnswerToClient(answer);  // отсылаем ответ клиенту
}

void Widget::sendAnswerToClient(QString &str){ // отсылаем сообщение очередному клиенту об успешном соединении
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (quint16)0;
    out << str;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
    TcpSocket->write(block);
}

void Widget::slotReadAnswer(){
    TcpSocket = (QTcpSocket*)sender();
    QString str;
    QDataStream in(TcpSocket);
    in.setVersion(QDataStream::Qt_4_5);
    for (;;) {
        if (!blockSize) {
            if (TcpSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> blockSize;
        }

        if (TcpSocket->bytesAvailable() < blockSize) {
            break;
        }
        in >> str;
        blockSize = 0;
        Chat->append(str);
    }
  label_answer->setText(str);
}

void Widget::send_letter_to_client(){
    QString str;
    str = letter->text();
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (quint16)0;
    out << str;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
    TcpSocket->write(block);
}




Ещё есть одна странная вещь. Беру пример из книги Макса Шлее, Server, с моей программы на неё приходят сообщения, а вот на мою никак не доходят...
call_me_Frank Дата 25.10.2010, 12:09
  спасибо за ответы!...щас всё взвешу и буду воплощать 8)
Sokoloff Дата 21.10.2010, 10:50
 
Цитата(Litkevich Yuriy @ 21.10.2010, 0:43) *
Цитата(call_me_Frank @ 20.10.2010, 17:18) *
что бы сервер посылал некоторый сигнал по таймеру всем клиентам, который по сути - синхроимпульс
я делал так:
В каждом узле есть свои часы.
В системе есть широковещательная команда - установка времени.

Ведущее устройство посылает установку времени,
периодически на каждом узле просматривается время и ведётся табличка корректирующая (на ведущем устройстве).
Если время расходится сильно, то ведущий опять посылает широковещательную установку времени.

Все события регистрируются узлами самостоятельно


"Все украдено до нас", это называется NTP и работает на всех распространенных системах.
Алексей1153 Дата 21.10.2010, 6:09
 
Цитата(call_me_Frank @ 21.10.2010, 0:07) *
только, думаю, сервер сам будет посылать данные на рабочие места, ведь опрос сервера - это трата времени, нет?

сервер - штука достаточно пассивная в сети, как это ни странно ) Опрашивать должны именно клиенты. Если опросом будет заниматься сервер, это будет более тормозным занятием
Litkevich Yuriy Дата 20.10.2010, 23:43
 
Цитата(call_me_Frank @ 20.10.2010, 17:18) *
что бы сервер посылал некоторый сигнал по таймеру всем клиентам, который по сути - синхроимпульс
я делал так:
В каждом узле есть свои часы.
В системе есть широковещательная команда - установка времени.

Ведущее устройство посылает установку времени,
периодически на каждом узле просматривается время и ведётся табличка корректирующая (на ведущем устройстве).
Если время расходится сильно, то ведущий опять посылает широковещательную установку времени.

Все события регистрируются узлами самостоятельно
call_me_Frank Дата 20.10.2010, 21:07
  "КОМП-СЕРВЕР(на нём БД и программа-сервер. С БД работает только эта программа и только локально на этом компе)
все железяки шлют сообщения сразу серверу, сервер пишет данные в базу.
далее, хвостом существует админка и рабочие места, которые цепляются опять-таки к программе-серверу. Рабочие места периодически опрашивают сервер на наличие новых данных, а также шлют сами, если надо. Возможен вариант извещения рабочих мест сервером о событиях." - ну, собственно, почти к этому я и пришел)) только, думаю, сервер сам будет посылать данные на рабочие места, ведь опрос сервера - это трата времени, нет?

"админка позволяет через посредство программы-сервера менять настройки системы и базы." - у меня была идея сделать некую прогу-конфигуратор, которая будет напоминать Visio-программы, где конфигурация системы выстраивается диаграммами и заданием настроек. Думаю, это вполне возможно и достаточно удобно!

Алексей1153 Дата 20.10.2010, 20:56
  у нас используется такая организация системы СКУД:

КОМП-СЕРВЕР(на нём БД и программа-сервер. С БД работает только эта программа и только локально на этом компе)
все железяки шлют сообщения сразу серверу, сервер пишет данные в базу.

далее, хвостом существует админка и рабочие места, которые цепляются опять-таки к программе-серверу. Рабочие места периодически опрашивают сервер на наличие новых данных, а также шлют сами, если надо. Возможен вариант извещения рабочих мест сервером о событиях.

админка позволяет через посредство программы-сервера менять настройки системы и базы.
call_me_Frank Дата 20.10.2010, 20:40
  Отчего ж не рассказать) изначально планировал сделать систему сбора данных с внешних аппаратных устр-в, подключенных к разным компам связанным по сети. Однако, для того, что б система обладала некоторой гибкостью и возможностью надстройки, хотел сделать её модульной, с единым сервером с БД, где все данные будут сохр., а потом изыматься оттуда для отправки в программы отображения данных на этих же машинах.

пришел к такому варианту реализации: каждая программа (или программная часть, собирающая данные) при получении очередной порции данных (по своим временным сигналам, а не тому единому от сервера, как было изначально обозначено в сабже) отправляет их на сервер; тот, по уже известной ему конфигурации запущенных программ отображения (он "знает", какая на какой машине запущена/не запущена и какие именно данные ей нужны), отправляет только что полученные данные адресату для их отображения!)) от такая задумка
Алексей1153 Дата 20.10.2010, 19:17
 
Цитата(call_me_Frank @ 20.10.2010, 22:11) *
что система требует совсем другой организации

так расскажи, если не секрет :)
call_me_Frank Дата 20.10.2010, 19:11
  ладно, тему можно считать закрытой, потому что благодаря ответам и другим размышлениям пришел к выводу, что система требует совсем другой организации :rolleyes:

спасибо за твои быстрые советы ;)
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 18.5.2024, 15:52