Russian Qt Forum

Qt => Работа с сетью => Тема начата: Firefox от Февраля 26, 2014, 08:18



Название: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 08:18
Здравствуйте. Хочу спросить про следующее: у меня есть сервер на другой программе клиент. клиент отправляет в сервер некий набор символов(не большой умещается в один пакет), сервер в ответ присылает код получения пакета. Так например при определенном действии клиент отправляет несколько пакетов, то есть 5, смысл того, что клиент отправляет пакет получает ответ и сразу же отправляет следующий пакет и опять ждет ответ(так 5 пакетов подряд). если он не получил один из ответов то далее не шлет пакет свой следующий. Загвозка в том, что если я ставлю точку останова в слот slot_readyRead()(генерится по сигналу readyRead()) на сервере, или при записи на клиенте, то все работает чудесно и все 5 пакетов доходят. если запускать без точки останова, то второй пакет от клиента записывается в сеть, а на сервере сигнал readyRead() не генерируется, и вся цепочка останавливается, так как клиент ждет подтверждения получения пакета, а сервер не видит сам пакет. Работаю в Windows 7. Подскажите в чем может быть причина такого поведения. Увеличить время до отправки пакета на клиенте или кидать постоянно в сеть пакеты до получения ответа не могу, так как программа написана другим человеком и уже закончена и не корректируется. Могу менять только на стороне сервера.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Bepec от Февраля 26, 2014, 08:30
Увеличь буфер сокета, если данных много.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 08:42
увеличила в 10 раз размер буфера на стороне сервера, если я правильно поняла, но проблему так это и не решило, сигнал readyRead() не пришел потому до чтения ещё не добрались
Код:
 quint64 ReadDataSize=socket->read(dataPacket,(LenthPacket+1)*10);


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 09:12
Нужен код  :)


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: LisandreL от Февраля 26, 2014, 09:32
Вы в курсе, что TCP - это протокол потоковой передачи данных и никак не гарантирует сохранения границ пакетов (может склеивать или нарезать их по своему усмотрению)?
То есть например вы быстро отсылаете 5 своих маленьких пакетов, TCP упаковывает их все в 1 пакет и сигнал readyRead() будет всего 1 (и все данные сразу доступны).


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 09:35
Вы в курсе, что TCP - это протокол потоковой передачи данных и никак не гарантирует сохранения границ пакетов (может склеивать или нарезать их по своему усмотрению)?
То есть например вы быстро отсылаете 5 своих маленьких пакетов, TCP упаковывает их все в 1 пакет и сигнал readyRead() будет всего 1 (и все данные сразу доступны).

я как понял, там жестко отсылается по одному пакетику и следующий отправляется только по приходу подтверждения.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 09:42
поняли вы правильно.
вот код сервера
Код:
//ModulExchange .h
#ifndef MODULEEXCHANGE_H
#define MODULEEXCHANGE_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QStringList>
#include "common_gs.h"
class ModuleExchange : public QObject
{
    Q_OBJECT
public:
    explicit ModuleExchange(QObject *parent = 0);
    int portInput;
    _PAR_SORD parFromSord; // структура для записи текущих параметров
    QByteArray head; // Заголовок пакета 0xe0,0xe3,0xe5,0xe7
    // установка порта на прослушивание
    void setPort(int port);
    // отправка данных
    void PacketSend(QByteArray);
    bool _connected;
   
signals:
    // есть соединение по определенному порту
    void connected();
    // нет соединения по конкретному порту
    void disconnected();
   
public slots:
    // включение или отключение прослушки отпределенного порта на сервере.
    void setEnableInput(bool _enable);
    // новое соединение
    void slot_new_connection();
    // пришел сигнал разрыва соединения
    void slot_disconnected();


     //слот чтения пакета
    void slot_readyRead();
protected:
    QTcpServer *server;
    QTcpSocket * socket;

    virtual void parsePacket(QByteArray _packet);

   
};
}

Код:
Modulexchange.cpp

#include "moduleexchange.h"
const QString packetSeparator="|";
const QString endSeparator="*";
ModuleExchange::ModuleExchange(QObject *parent) :
    QObject(parent)
{

     server= new QTcpServer(this);
     connect(server, SIGNAL(newConnection()),SLOT(slot_new_connection()));
     portInput=0;
     _connected=false;

     head.resize(4);
     head[0]=0xe0;
     head[1]=0xe3;
     head[2]=0xe5;
     head[3]=0xe7;

}
void ModuleExchange::slot_new_connection()
{
    socket=server->nextPendingConnection();
    connect(socket,SIGNAL(disconnected()),this, SLOT(slot_disconnected()));
    connect(socket,SIGNAL(readyRead()),this, SLOT(slot_readyRead()));
    _connected=true;
}
void ModuleExchange::slot_disconnected()
{
    socket->deleteLater();
}
void ModuleExchange::setPort(int port)
{
    portInput=port;
}
void ModuleExchange::setEnableInput(bool _enable)
{
    if(portInput==0)
        return;
    if(_enable)
    {
        server->listen(QHostAddress::Any,portInput);
    }
    else
    {
        server->close();
    }
}

void ModuleExchange::slot_readyRead()
{
    if(!socket)
        return;

    quint64 NextBlockSize=0;
    QByteArray Packet;
    NextBlockSize=socket->bytesAvailable();
    if(NextBlockSize<1)
        return;
    char dataP[NextBlockSize];
    Packet.clear();
    quint64 LenthPacket=0;
    socket->peek(dataP,NextBlockSize);
    Packet.setRawData(dataP,NextBlockSize);
    // номер в строке конца пакета("*")
    // для всех протоколов обмена кроме протокола с прибором 16
    if((LenthPacket=Packet.indexOf(endSeparator))>0 && LenthPacket<=NextBlockSize)
    {
       // есть конец пакета
        char dataPacket[LenthPacket];
        quint64 ReadDataSize=socket->read(dataPacket,(LenthPacket+1));
        Packet.setRawData(dataPacket,LenthPacket);
        parsePacket(Packet);
        if(ReadDataSize<NextBlockSize)
        {
            slot_readyRead();// принято больше данных чем должно быть в одном пакете
        }
    }
    // наличие заголовка пакета при обмене с 16 прибором
    else if(Packet.contains(head))
    {
        //ДОДЕЛАТЬ НЕ ВЕРНО ЕСЛИ ПАКЕТ ПРИХОДИТ ЗА 2 РАЗА, ТО У ВТОРОГО НЕТ ЗАГОЛОВКА
        char dataPacket[LenthPacket];
        quint64 ReadDataSize=socket->read(dataPacket,NextBlockSize);
        Packet.setRawData(dataPacket,NextBlockSize);
        parsePacket(Packet);
        if(ReadDataSize<NextBlockSize)
        {
            slot_readyRead();// не все данные считаны из канала
        }
    }
    else
    {
        slot_readyRead(); // в пакете нет символа конца пакета и заголовка,
                          //т.е. меньше данных чем должно быть
                          //или данные не соответствуют протоколам
    }
}
void ModuleExchange::parsePacket(QByteArray _packet)
{
;
}
void ModuleExchange::PacketSend(QByteArray _packet)
{
    if(!_connected)
        return;
    if(socket->state()!=QAbstractSocket::ConnectedState)
        return;
     int sz=socket->write(_packet,_packet.size());
     if(sz!=_packet.size())
    {
        qDebug()<<"not all information writes to protocol";
    }
}

Разбор пакета от нужного клиента

Код:
.h
#ifndef STRUCTURAEXCHANGE2D8D_H
#define STRUCTURAEXCHANGE2D8D_H

#include <QObject>
#include <QSettings>

#include "moduleexchange.h"

class StructuraExchange2D8D : public ModuleExchange
{
    Q_OBJECT
public:
    explicit StructuraExchange2D8D(QObject *parent = 0);
    QSettings *seting;
    void SendData_2d_8d(QByteArray _pack);
   
signals:
    void Radiation_on(QByteArray);// включено излучение на отправку АТГС данных в сорде
public slots:

protected:
    void parsePacket(QByteArray _packet);
   
};

#endif // STRUCTURAEXCHANGE_H
Код:
.cpp
#include "structuraexchange_2D8D.h"
//#include "/Structure/Structure.h"
#define packetSeparator "|"

StructuraExchange2D8D::StructuraExchange2D8D(QObject *parent) :
    ModuleExchange(parent)
{
    seting= new QSettings(
        tr("net.ini"),
        QSettings::IniFormat,
        this );
    seting->beginGroup("NET_PORT");
    int PORT=seting->value("_PORT_2D_8D", QString("")).toInt();
    qDebug()<<"PORT_client_2D8D"<<PORT;
    seting->endGroup();
    setPort(PORT);
    setEnableInput(true);
}
void StructuraExchange2D8D::parsePacket(QByteArray _packet)
{
   QByteArray arrData;
   arrData.resize(0);
   qDebug()<<"_packet from 28D"<<_packet;
   if(_packet.size()>=1)
   {
         QString str;
         str=QString::fromAscii(_packet);
         str=_packet.mid(0,2);
       
         if(str=="@C")
         {
             _packet=_packet.right(3);
             _packet=_packet.left(2);
             switch(_packet.toShort())
             {
                 case 0: parFromSord.Mos=0;break;
                 case 1: parFromSord.Mos=2;break;
                 case 4: parFromSord.Mos=3;break;
                 default: break;
             }
              SendData_2d_8d("@Y*");
         }
         if(str=="@U")
         {
              SendData_2d_8d("@Y*");
         }
         if(str=="@I")
         {
           emit SendData_2d_8d("@I");
         }
         if(str=="@A")
         {
              SendData_2d_8d("@A8F*");
         }
         if(str=="#M" )
         {
             _packet=arrData.right(2);
             _packet=arrData.left(1);

             switch(_packet.toShort())
             {
                 case 1:
                 parFromSord.Nap=2;
                 break;  // НИЗ
                 case 3:
                 parFromSord.Nap=3;
                 break;  // верх
                 default: break;
             };
             SendData_2d_8d("#Y*");
         }
         if(str=="#D" || str=="#U" )
         {
              SendData_2d_8d("#Y*");
         }
         if(str=="#R")
         {
             SendData_2d_8d("#Y*");
             emit Radiation_on(_packet.mid(2,1));
         }

     }

}

void StructuraExchange2D8D::SendData_2d_8d(QByteArray _pack)
{
     PacketSend(_pack);
     qDebug()<<"Packet_sent_2D_8D"<<_pack;
}


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 09:43
функция отправки данных на клиенте
Код:
void work_2d_8d::send_2d_8d( QString command )
{
static int shp=0;
QByteArray out;
QDataStream data_out( &out, QIODevice::WriteOnly );
data_out.setVersion( QDataStream::Qt_4_2 );
QByteArray command_asci;
command=command.toUpper();
command_asci=command.toAscii();

    data_out.writeRawData((char*)command_asci.data(), command_asci.size());
int sz=0;
    out.resize(out.size()*100);
sz=m_pTcpSocket->write( out );
    qDebug()<<"command28D_OUT"<<out<<"sz"<<sz;
    m_pTcpSocket->flush();
QString str_deb;
str_deb.sprintf( "%3d send: ", shp%1000 );
QString str;
for (int i=0; i<sz; i++ )
{
str.sprintf("%x ", (char)out[i] );
str_deb+=str;
}
emit type_data_signal( nPort, command+"  "+str_deb );

shp++;
}


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 10:03
1. А как определяете, что пакет второй точно отправляется с клиента?
2. А повторный вызов slot_new_connection() не происходит случайно?


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 10:21
1) ну я просто распечатала сам пакет и размер отправленных данных совпадает с размером пакета, и потом когда я работаю с точками останова я вижу что ко мне этот пакет приходит.
sz=m_pTcpSocket->write( out );
    qDebug()<<"command28D_OUT"<<out<<"sz"<<sz;!!!!!!

2) соединений генерится столько сколько клиентов подключается. вроде должно быть на каждый по одному


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 10:36
1) ну я просто распечатала сам пакет и размер отправленных данных совпадает с размером пакета, и потом когда я работаю с точками останова я вижу что ко мне этот пакет приходит.
sz=m_pTcpSocket->write( out );
    qDebug()<<"command28D_OUT"<<out<<"sz"<<sz;!!!!!!

2) соединений генерится столько сколько клиентов подключается. вроде должно быть на каждый по одному

1. Write не отправляет данные, а записывает во внутренний буфер сокета и не говорит ничего о факте непосредственной отправки данных.
2. Ну это да, но указатель на сокет используется один для всех - мало ли - проверьте)
3. Не знаю влияет ли, но может убрать рекурсивные вызовы слота slot_readyRead()? Он сам вызовется, когда будут данные  - незачем его дергать просто так вручную.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 10:57
что может точно говорить о непосредственной отправке данных. чтобы они были видны для сокета на стороне сервера?
слот рекурсивно вызывается но в данном случае туда не заходит программа, то есть зацикливания нет, а вызывается от чтобы если придут за раз несколько пакетов по одному считывать из сети и отправлять в обработку.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 11:09
На сколько я помню, можно судить по void QIODevice::bytesWritten ( qint64 bytes ) [signal].
А разве вы считываете по одному пакету? В слоте вы читаете сразу все доступные байты и потом уже парсите, на сколько я понял по коду.
Так же для отладки сокетов мне было удобно следить за сменой их состояний по void QAbstractSocket::stateChanged ( QAbstractSocket::SocketState socketState ) [signal].


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 11:15
попробую посмотреть спасибо, а считываю я по одному пакету, до символа "*" - это признак конца пакета, фенкция peek не считывает, данные после неё остаются в канале.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 11:23
Да, пардон, пропустил.
И конечно следите за ошибками сокета! Проблема может быть совсем в другом, но лишним это в любом случае не будет и в отладке тоже поможет!


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 26, 2014, 13:00
состояние сокета отслеживаю теперь. по всем клиентам ConnectedState, пока клиент не отключиться. дописала в рограмме клиента после функции write() 
emit bytesWritten(out.size());

h.
virtual void bytesWritten(int);

но толку пока 0


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 26, 2014, 14:04
bytesWritten сам эмитится - к нему подключаться надо.
А вы тестируете сразу с несколькими клиентами?


Название: Купить Sony Cyber-shot DSC-TF1 (черный)
Отправлено: plauperloaf от Февраля 26, 2014, 23:11
Привет уважаемые пользователи.
Хочу предложить Вам наши новые поступления, которые отлично подойдут Вам или Вашим друзьям и Любимым в качестве подарка.
Спешите делать добро...
Вот некоторые из популярных предложений:
 
https://ad.admitad.com/goto/9ca789394918526b6c35c4d17e040f/?ulp=http%3A%2F%2Fwww.svyaznoy.ru%2Fcatalog%2Fnotebook%2F7045%2F1491220%3Fcity_id%3D133%26utm_medium%3Dcpa%26utm_source%3Dadmitad - "Logitech M525 (черный)"

https://ad.admitad.com/goto/9ca789394918526b6c35c4d17e040f/?ulp=http%3A%2F%2Fwww.svyaznoy.ru%2Fcatalog%2Fnotebook%2F7045%2F1491220%3Fcity_id%3D133%26utm_medium%3Dcpa%26utm_source%3Dadmitad - http://static.svyaznoy.ru/upload/iblock/e60/29506785_700x700min_1.jpg

Мышь Logitech M525 разработана для любителей современных компьютерных игр. Дизайн эргономичного корпуса оптимизирован для комфортного захвата рукой. Представленная модель вполне пригодна для продолжительной работы. Радиус действия беспроводной связи достигает десяти метров. В качестве источника питания для Logitech M525 используются две щелочные сменные батарейки типа AA, время разряда которых составляет порядка трех лет.

https://ad.admitad.com/goto/9ca789394918526b6c35c4d17e040f/?ulp=http%3A%2F%2Fwww.svyaznoy.ru%2Fcatalog%2Fnotebook%2F7045%2F1491220%3Fcity_id%3D133%26utm_medium%3Dcpa%26utm_source%3Dadmitad - КУПИТЬ ПРЯМО СЕЙЧАС Logitech M525 (черный) за 1150 руб.


Ключевые слова:
купить Logitech M525 (черный)
заказать Logitech M525 (черный)
цена на Logitech M525 (черный)
интернет магазин, купить Logitech M525 (черный)
Logitech M525 (черный) в интернет магазине в Москве
купить Logitech M525 (черный) в Москве
купить Logitech M525 (черный) в Киеве
купить Logitech M525 (черный) в Санкт-Петербурге


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 27, 2014, 10:05
Да у меня несколько клиентов. проблема оказалась именно в этом. пока я её не решила, но суть в том что есть несколько классов наследуемые от modulExchange класса( в нем происходит обработка connect, readyread, disconnect..). Далее в главном классе на все эти клиентские классы создаются указатели. Так вот если оставить одного клиента, а остальных отключить, то проблем не возникает, а если во время работы какой-нибудь другой клиент отправляет данные, то с сокетом нужного мне клиента происходит что-то. я не до конца поняла почему так происходит, ведь я делаю несколько указателей и для каждого, как я думала, должен свой экземпляр modulExchange  в памяти быть.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 27, 2014, 10:25
Не очень понял, если честно))
Так может проблема как раз в том, что работая с одним клиентом, подключается второй и сервер просто забывает про первого?)) Как только приходит сигнал newConnection, вы ведь сразу же переключаетесь на новое соединение и работаете уже с ним. Разве я не прав?


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 27, 2014, 10:42
не должно так быть, сейчас  приведу код более полно чтоб было понятно


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 27, 2014, 10:57
// ГЛАВНЫЙ КЛАСС ОБМЕНА
Код:
#ifndef MODULEEXCHANGE_H
#define MODULEEXCHANGE_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QStringList>
#include <QThread>
#include "common_gs.h"
class ModuleExchange : public QObject
{
    Q_OBJECT
public:
    explicit ModuleExchange(QObject *parent = 0);
    int portInput;
    _PAR_SORD parFromSord; // структура для записи текущих параметров управления на тко сорд гс
    QByteArray head; // Заголовок пакета 0xe0,0xe3,0xe5,0xe7
    // установка порта на прослушивание
    void setPort(int port);
    // отправка данных
    void PacketSend(QByteArray);
    bool _connected;
   
signals:
    // есть соединение по определенному порту
    void connected();
    // нет соединения по конкретному порту
    void disconnected();
   
public slots:
    // включение или отключение прослушки отпределенного порта на сервере.
    void setEnableInput(bool _enable);
    // новое соединение
    void slot_new_connection();
    // пришел сигнал разрыва соединения
    void slot_disconnected();


     //слот чтения пакета
    void slot_readyRead();
    // изменение состояния сокета
    void soc_chd(QAbstractSocket::SocketState);





protected:
    QTcpServer *server;
    QTcpSocket * socket;

    virtual void parsePacket(QByteArray _packet);

   
};

#endif // MODULEEXCHANGE_H
Код:
#include "moduleexchange.h"
const QString packetSeparator="|";
const QString endSeparator="*";
ModuleExchange::ModuleExchange(QObject *parent) :
    QObject(parent)
{

     server= new QTcpServer(this);
     connect(server, SIGNAL(newConnection()),SLOT(slot_new_connection()));
     portInput=0;
     _connected=false;

     head.resize(4);
     head[0]=0xe0;
     head[1]=0xe3;
     head[2]=0xe5;
     head[3]=0xe7;

}
void ModuleExchange::slot_new_connection()
{
    qDebug()<<__FUNCTION__;
    socket=server->nextPendingConnection();
    qDebug()<<"port"<<socket->localPort();
    connect(socket,SIGNAL(disconnected()),socket, SLOT(slot_disconnected()));
    connect(socket,SIGNAL(readyRead()),this, SLOT(slot_readyRead()));
    connect(socket,SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(soc_chd(QAbstractSocket::SocketState)));
    _connected=true;

}
void ModuleExchange::slot_disconnected()
{
    socket->deleteLater();
}
void ModuleExchange::setPort(int port)
{
    portInput=port;
}
void ModuleExchange::setEnableInput(bool _enable)
{
    if(portInput==0)
        return;
    if(_enable)
    {
        server->listen(QHostAddress::Any,portInput);
    }
    else
    {
        server->close();
    }
}

void ModuleExchange::slot_readyRead()
{
    qDebug()<<__FUNCTION__;
    if(!socket)
        return;

    quint64 NextBlockSize=0;
    QByteArray Packet;
    NextBlockSize=socket->bytesAvailable();
    if(NextBlockSize<1)
        return;
    char dataP[NextBlockSize];
    Packet.clear();
    quint64 LenthPacket=0;
    socket->peek(dataP,NextBlockSize);
    Packet.setRawData(dataP,NextBlockSize);
    // номер в строке конца пакета("*")
    // для всех протоколов обмена кроме протокола с прибором 16
    if((LenthPacket=Packet.indexOf(endSeparator))>0 && LenthPacket<=NextBlockSize)
    {
        // есть конец пакета
        char dataPacket[LenthPacket];
        quint64 ReadDataSize=socket->read(dataPacket,(LenthPacket+1));
        Packet.setRawData(dataPacket,LenthPacket);
        parsePacket(Packet);
        if(ReadDataSize<NextBlockSize)
        {
            slot_readyRead();// принято больше данных чем должно быть в одном пакете
        }
    }
    // наличие заголовка пакета при обмене с 16 прибором
    else if(Packet.contains(head))
    {
        //ДОДЕЛАТЬ НЕ ВЕРНО ЕСЛИ ПАКЕТ ПРИХОДИТ ЗА 2 РАЗА, ТО У ВТОРОГО НЕТ ЗАГОЛОВКА
        char dataPacket[LenthPacket];
        quint64 ReadDataSize=socket->read(dataPacket,NextBlockSize);
        Packet.setRawData(dataPacket,NextBlockSize);
        parsePacket(Packet);
        if(ReadDataSize<NextBlockSize)
        {
            slot_readyRead(); //не все данные считаны из канала
        }
    }
    else
    {
        slot_readyRead(); // в пакете нет символа конца пакета и заголовка,
                          //т.е. меньше данных чем должно быть
                          //или данные не соответствуют протоколам
    }
}
void ModuleExchange::parsePacket(QByteArray _packet)
{
;
}
void ModuleExchange::PacketSend(QByteArray _packet)
{
    qDebug()<<"1";
    if(!_connected)
        return;
    if(socket->state()!=QAbstractSocket::ConnectedState)
        return;
    qDebug()<<"2";
     int sz=socket->write(_packet,_packet.size());
     if(sz!=_packet.size())
    {
        qDebug()<<" not all information writes to protocol";
    }

}
void ModuleExchange::soc_chd(QAbstractSocket::SocketState)
{
    qDebug()<<"port"<<socket->localPort();
    switch(socket->state())
    {
    case  QAbstractSocket::UnconnectedState:
       { qDebug("QAbstractSocket::UnconnectedState"); break;}
    case  QAbstractSocket::HostLookupState:
       { qDebug("QAbstractSocket::HostLookupState");break;}
    case  QAbstractSocket::ConnectingState:
       { qDebug("QAbstractSocket::ConnectingState");break;}
    case  QAbstractSocket::ConnectedState:
       { qDebug("QAbstractSocket::ConnectedState");break;}
    case  QAbstractSocket::BoundState:
       { qDebug("QAbstractSocket::BoundState");break;}
    case  QAbstractSocket::ClosingState:
       { qDebug("QAbstractSocket::ClosingState");break;}
    case  QAbstractSocket::ListeningState:
       { qDebug("QAbstractSocket::ListeningState");break;}
    default:
       { qDebug("QAbstractSocket DONT KNOW");break;}
    };

}


// классы для клиентов каждаго
// 1 клиент
Код:
#ifndef STRUCTURAEXCHANGE_16KP_H
#define STRUCTURAEXCHANGE_16KP_H

#include <QObject>
#include <QSettings>
#include <QTextCodec>
#include "math.h"
#include "moduleexchange.h"
#include <QThread>
class StructuraExchange_16KP : public ModuleExchange

{
    Q_OBJECT
public:
    explicit StructuraExchange_16KP(QObject *parent = 0);
    QSettings *seting;


    unsigned short count_packet_to16KP;
   
signals:
   void SignalRezim(unsigned short,unsigned short);// сигнал смены режима
    void SignBufferForSend(QByteArray);
public slots:
    // отправка данных по протоколам обмена 16 прибора
    void slotSendDataToSord_16KP(unsigned short padr, unsigned short evnt, bool flag_s_h,double s_h, bool flag_dopInfo,double dopInfo,QString info);
protected:
    void parsePacket(QByteArray _packet);
   
};
Код:
#include "structuraexchange_16KP.h"
#define packetSeparator "|"

StructuraExchange_16KP::StructuraExchange_16KP(QObject *parent) :
    ModuleExchange(parent)
{
 //   moveToThread(this);
    count_packet_to16KP=0;
    seting= new QSettings(
        tr("net.ini"),
        QSettings::IniFormat,
        this );
    seting->beginGroup("NET_PORT");
    int PORT=seting->value("_PORT_16KP", QString("")).toInt();
    qDebug()<<"PORT_client_16KP"<<PORT;
    seting->endGroup();
    setPort(PORT);
    setEnableInput(true);


}
void StructuraExchange_16KP::parsePacket(QByteArray _packet)
{
    qDebug()<<"arrData16KP"<<_packet;
    QByteArray arrData,rezData;
    int indTitle=0;
    if(_packet.size()>=1)
    {
        indTitle=_packet.indexOf(head,0);
        if(indTitle>=0)
        {
            rezData=_packet.mid(indTitle+3,_packet.size()-4);// слабое место переделать потом

            unsigned short padr=rezData.at(3);
            unsigned short part2=rezData.at(2);
            part2=part2<<8;
            padr=padr|part2;
           // qDebug()<<"padr"<<padr;

                switch(padr)
                {

                case 19:
                    parFromSord.rezim=2;
                    parFromSord.diapazon=rezData.at(5);
                    emit SignalRezim(parFromSord.rezim,parFromSord.diapazon);
                    break;

                case 20:
                    parFromSord.rezim=2;
                    parFromSord.diapazon=rezData.at(5);
                    emit SignalRezim(parFromSord.rezim,parFromSord.diapazon);
                    break;

                case 21:
                    parFromSord.rezim=1;
                    parFromSord.diapazon=rezData.at(5);
                    emit SignalRezim(parFromSord.rezim,parFromSord.diapazon);
                    break;

                case 17:
                    parFromSord.rezim=3;
                    parFromSord.diapazon=rezData.at(5);
                    emit SignalRezim(parFromSord.rezim,parFromSord.diapazon);
                    break;
                    //case OTU_REZIM: parFromSord.rezim=0; break;
                    case BUFF_ATGS:
                    rezData=rezData.mid(5,rezData.size()-4);
                   // qDebug()<<"SIZE"<<QString().number(rezData.size());
                    emit SignBufferForSend(rezData);

                    break;
                case BUFF_KS:
                    rezData=rezData.mid(5,rezData.size()-4);
                    emit SignBufferForSend(rezData);
                    break;

                default: break;
             }
               
        }
    }
}

void StructuraExchange_16KP::slotSendDataToSord_16KP(unsigned short padr, unsigned short evnt, bool flag_s_h,double s_h, bool flag_dopInfo,double dopInfo,QString info)
{
   
       int sz=0;

//       if(socket_out->state()!=QAbstractSocket::ConnectedState)
//            return;

       QByteArray ass;
       QByteArray arr;
       QByteArray Packet;
       do
       {
           /** Шапка пакета **/
           arr.resize(0);
           arr.append(head); // заголовок


           ass.resize(0);
           ass.append(count_packet_to16KP);
           ass.resize(2);
           arr.append(ass);// счетчик пакетов

           ass.resize(0);
           ass.append(padr);
           ass.resize(2);
           arr.append(ass);// подадрес

           ass.resize(0);
           ass.append(evnt);
           ass.resize(2);
           arr.append(ass);// код события
           /** Шапка пакета закончилась **/

           /** Счетчик пакетов **/
           count_packet_to16KP++;
           if(count_packet_to16KP>=pow(2,16))
              count_packet_to16KP=0;
            /** Счетчик пакетов закончился**/

     

         
           if(flag_s_h==true)
           {
               ass.resize(0);
               ass.append(abs(s_h));
               ass.resize(2);
               arr.append(ass);
           }
           /** Есть дополнительня информация **/
           if(flag_dopInfo==true)
           {
               ass.resize(0);
               ass.append(abs(dopInfo));
               ass.resize(2);
               arr.append(ass);// дополнительная информация
           }
            /** Дополнительня информация закончилась**/

           /** Есть информационные символы **/
           ass.resize(0);
           if(info.size()>=4)
           {

                   info.toUpper();
                   QTextCodec *codec= QTextCodec::codecForName("IBM 866");
                   ass=codec->fromUnicode(info);

                   Packet.resize(0);
                   Packet.append(arr);
                   if(ass.size()>=INFO_LENGHT)
                   {
                       Packet.append(ass.left(INFO_LENGHT));
                       info=info.right(ass.size()-INFO_LENGHT);
                   }
                   else
                   {
                       Packet.append(ass);

                       ass.clear();
                   }
                   Packet.resize(72);
                   PacketSend(Packet);


           }
           else
           {
              Packet.resize(0);
              Packet.append(arr);


               Packet.resize(72);
               PacketSend(Packet);


           }

       }
       while(ass.size()>0);
    /** Конец записи информации **/

}


#endif // STRUCTURAEXCHANGE_H

// 2 клиент
Код:
#ifndef STRUCTURAEXCHANGE2D8D_H
#define STRUCTURAEXCHANGE2D8D_H

#include <QObject>
#include <QSettings>
#include <QTimer>
#include "moduleexchange.h"

class StructuraExchange2D8D : public ModuleExchange
{
    Q_OBJECT
public:
    explicit StructuraExchange2D8D(QObject *parent = 0);
    QSettings *seting;
    void SendData_2d_8d(QByteArray _pack);

   
signals:
    void Radiation_on(QByteArray);
public slots:

protected:
    void parsePacket(QByteArray _packet);
   
private slots:
    void sss();
};

#endif // STRUCTURAEXCHANGE_H
Код:
#include "structuraexchange_2D8D.h"
//#include "/Structure/Structure.h"
#define packetSeparator "|"

StructuraExchange2D8D::StructuraExchange2D8D(QObject *parent) :
    ModuleExchange(parent)
{
   
    seting= new QSettings(
        tr("net.ini"),
        QSettings::IniFormat,
        this );
    seting->beginGroup("NET_PORT");
    int PORT=seting->value("_PORT_2D_8D", QString("")).toInt();
    qDebug()<<"PORT_client_2D8D"<<PORT;
    seting->endGroup();
    setPort(PORT);
    setEnableInput(true);
}



void StructuraExchange2D8D::parsePacket(QByteArray _packet)
{
   QByteArray arrData;
   arrData.resize(0);
   qDebug()<<"_packet from 2D_8D"<<_packet;
   if(_packet.size()>=1)
   {
         QString str;
         str=QString::fromAscii(_packet);
         str=_packet.mid(0,2);
       
         if(str=="@C")
         {
             _packet=_packet.right(3);
             _packet=_packet.left(2);
             switch(_packet.toShort())
             {
                 case 0: parFromSord.Moshnost=0;break;
                 case 1: parFromSord.Moshnost=2;break;
                 case 4: parFromSord.Moshnost=3;break;
                 default: break;
             }
           
              SendData_2d_8d("@Y*");
         }
         if(str=="@U")
         {
              SendData_2d_8d("@Y*");
         }
         if(str=="@I")
         {
           emit SendData_2d_8d("@I");
         }
         if(str=="@A")
         {
              SendData_2d_8d("@A8F*");
         }
         if(str=="#M" )
         {
             _packet=arrData.right(2);
             _packet=arrData.left(1);

             switch(_packet.toShort())
             {
                 case 1:
                 parFromSord.Napravlenie=2;
                 break; 
                 case 3:
                 parFromSord.Napravlenie=3;
                 break;
                 default: break;
             };
             SendData_2d_8d("#Y*");
         }
         if(str=="#D" || str=="#U" )
         {
              SendData_2d_8d("#Y*");
         }
         if(str=="#R")
         {
             SendData_2d_8d("#Y*");
             emit Radiation_on(_packet.mid(2,1));
         }

     }

}

void StructuraExchange2D8D::SendData_2d_8d(QByteArray _pack)
{
     PacketSend(_pack);
     qDebug()<<"Packet_sent_2D_8D"<<_pack;
}
// Гланый класс программы
Код:
#include "Exchange_my/structuraexchange_16KP.h"
#include "Exchange_my/structuraexchange_2D8D.h"

private:
 StructuraExchange_16KP *exch_16_kp;
 StructuraExchange2D8D *exch_2d8d;
Код:
//.cpp
exch_16_kp= new StructuraExchange_16KP(this);
exch_2d8d=new StructuraExchange2D8D(this);

    connect(this,SIGNAL(SignalSend(QByteArray)),exch_pod,SLOT(DataSend(QByteArray)));
    connect(this,SIGNAL(Signal_SendDataToSord_16KP(unsigned short,unsigned short,bool,double,bool,double,QString)),exch_16_kp,SLOT(slotSendDataToSord_16KP(unsigned short,unsigned short,bool,double,bool,double,QString)));


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 27, 2014, 11:34
Ничего понятней не стало)) Объясните лучше, почему должна работать вот эта инструкция) Конечно она работать будет, но с каждым приходом нового коннэкта, текущий коннэкт будет "забываться", разве я не прав?? В указателе socket всегда будет сокет самого нового подключения и в итоге когда много клиентов, все будут работать с сокетом самого последнего подключения  ;D.

Код:
connect(server, SIGNAL(newConnection()),SLOT(slot_new_connection()));

void ModuleExchange::slot_new_connection()
{
    qDebug()<<__FUNCTION__;
    socket=server->nextPendingConnection();
    qDebug()<<"port"<<socket->localPort();
    connect(socket,SIGNAL(disconnected()),socket, SLOT(slot_disconnected()));
    connect(socket,SIGNAL(readyRead()),this, SLOT(slot_readyRead()));
    connect(socket,SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(soc_chd(QAbstractSocket::SocketState)));
    _connected=true;

}


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 27, 2014, 13:02
по моей логике эту инструкцию наследуют 2 класса и на них разные указатели. и выделяется под каждый класс своя память new
Код:
StructuraExchange_16KP *exch_16_kp; 
 StructuraExchange2D8D *exch_2d8d;
exch_16_kp= new StructuraExchange_16KP(this);
exch_2d8d=new StructuraExchange2D8D(this);


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 27, 2014, 13:11
Так, да, пардон за невнимательность - код тяжко читается. Надо уточнить - Клиента всегда максимум два?  По одному каждого типа? Порты в настройках точно разные? Если да, то проблема где-то выше  ???


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Февраля 27, 2014, 13:42
клиентов больше но на каждый клиент свой тип, и если оставить только два то не работает.на каждого клиента свой порт.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Февраля 27, 2014, 14:08
И если один клиент, то все работает ок, а как только подключается второй, то сразу прекращает работать? А что при этом с состояниями сокетов и ошибками на них?


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Марта 01, 2014, 09:33
там получается если один клиент работает то все хорошо, если другой подключается но ничего не отправляет тоже все хорошо, а вот если два отправлять начинают то начинает все  тормозить.


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Марта 03, 2014, 10:51
Так тормозить или не работать?  ???


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Марта 04, 2014, 22:51
Ну если отправить один пакет ,то он не придет сразу(то есть вообще не придет), а вот если несколько пакетов послать, то придут все, но склеенные сразу 3-4 пакета. но мне как-бы надо один в ответ посылать. в общем я решила сама написать вторую программу клиента, а не брать чужую разработку, возможно ошибка и не у меня, по крайне мере я уже голову сломала, но ничего не нашла в своем обмене. спасибо большое за помощь всем и извините если отвлекла сильно своей проблемой. :)


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: OKTA от Марта 04, 2014, 22:56
я уже забыл, с чего все начиналось, а перечитывать лень  ;D
если пакеты склеиваются, используйте flush после каждого write для пакета - склеивание это нормально))


Название: Re: Не всегда приходят данные QTCpSocket
Отправлено: Firefox от Марта 06, 2014, 19:54
я-то знаю но вот может автор второй программы не знает этого