2012-03-15 4 views
6

두 개의 QT 앱이 있습니다. 한 응용 프로그램은 큰 데이터를 보유하는 것으로 간주 될 수 있으며 두 번째 응용 프로그램에 매초 약 10KB의 데이터 청크를 보냅니다.QTcpSocket은 때때로 데이터를 보내지 않습니다.

이전에 데이터를 전송하기 위해 QUdpSocket을 사용했지만 약 2 ~ 5K의 MTU 제한으로 인해 데이터를 나눠서 재결합해야하므로 QTcpSocket으로 전환했습니다.

때로는 QTcpSocket을 사용하여 데이터를 올바르게 전송하지만 (특히 데이터를 매우 자주 ~ 100ms마다 쓴 경우) 데이터가 전혀 전송되지 않습니다. 5 초 후에도. 때로는 여러 데이터 청크가 내부적으로 오랜 기간 (수 초) 버퍼링되어 함께 전송됩니다.

m_socket = new QTcpSocket(this); 
m_socket->connectToHost(QHostAddress::LocalHost, 45454); 

sendDataEverySec() 
{ 
    QByteArray datagram(10000, 'a'); 
    qint64 len = m_socket->write(datagram); 
    if(len != datagram.size()) 
      qDebug() << "Error"; //this NEVER occurs in MY case. 
    m_socket->flush(); 
} 

수신 측에서는 데이터가 도착한 시간을 알리기 위해 readyRead 신호를 사용합니다.

데이터가 즉시 전송되도록하려면 어떻게해야합니까? 내가하려고하는 것에 대한 더 좋은 대안이 있습니까?

편집 :: 1 초의 긴 간격을두고 글을 쓸 때마다 발신자가 데이터를 보낼 때마다 수신자 쪽에서 "QAbstractSocket::SocketTimeoutError"이 수신됩니다. 보낸 사람이 데이터를 자주 쓰는 경우이 오류가 수신되지 않습니다.
QTcpSocket을 사용하여 내가하는 방식대로 데이터를 스트리밍 할 수 있습니까?

편집 2 : 수신 측에서 readyRead 신호가 방출 될 때, 나는 다시 while(m_socket->waitForReadyRead(500))을 확인 중이었고이 때문에 "QAbstractSocket::SocketTimeoutError"이 발생했습니다. 또한이 검사는 단일 청크가 전달되지 못하게합니다.
문서를 더 읽은 후에는 새로운 데이터를 사용할 수있을 때 readyRead이 계속 발생하므로 waitForReadyRead이 필요하지 않습니다.
전송 된 모든 데이터를 수신하고 있지만 여전히 데이터가 즉시 수신되지 않습니다. 때로는 2-3 개의 청크가 병합됩니다. 이것은 데이터 읽기 등에서 수신자 측의 지연으로 인한 것일 수 있습니다.

+0

QAbstractSocket :: LowDelayOption 플래그를 setSocketOption API로 설정할 수 있습니까? – Kunal

+0

@Kunal, 나는 성공없이 LowDelayOption과 KeepAliveOption을 시도했다.흥미롭게도 송신자가 데이터를 보내 자마자 수신기는 "QAbstractSocket :: SocketTimeoutError"를 보여줍니다. 이것은 1 초 간격으로 데이터를 기록 할 때 발생합니다. –

+0

문제가 수신 측에 있다고 확신합니다. 수신 연결을 처리하는 방법을 알려주세요. – Koying

답변

2

readyRead 신호가 방출 될 때, 나는 다시 while(m_socket->waitForReadyRead(500))을 체크하고 있었고, 이것 때문에 "QAbstractSocket::SocketTimeoutError"을 얻고있었습니다. 또한이 검사는 단일 청크가 전달되지 못하게합니다.

문서를 더 읽은 후에는 새로운 데이터를 사용할 수있을 때 readyRead가 계속 출력되므로 waitForReadyRead이 필요하지 않습니다. 내 문제가 해결되었습니다.

0

클라이언트 서버 응용 프로그램에 대한 내 tipical 솔루션. 서버 측에서

:

CPP에
class Server: public QTcpServer { 

public: 
    Server(QObject *parent = 0); 
    ~Server(); 
private slots: 
    void readyRead(); 
    void disconnected(); 
protected: 
    void incomingConnection(int); 

}; 

:

클래스 클라이언트 : 공공 QTcpSocket {CPP에

public: 
    Client(const QHostAddress&, int, QObject* = 0); 
    ~Client(); 
    void Client::sendMessage(const QString&); 
private slots: 
    void readyRead(); 
    void connected(); 
public slots: 
    void doConnect(); 
}; 

:

클라이언트에서

void Server::incomingConnection(int socketfd) { 

    QTcpSocket *client = new QTcpSocket(this); 
    client->setSocketDescriptor(socketfd); 


    connect(client, SIGNAL(readyRead()), this, SLOT(readyRead())); 
    connect(client, SIGNAL(disconnected()), this, SLOT(disconnected())); 
} 

void Server::disconnected() { 
    QTcpSocket *client = (QTcpSocket*) sender(); 

    qDebug() << " INFO : " << QDateTime::currentDateTime() 
      << " : CLIENT DISCONNECTED " << client->peerAddress().toString(); 
} 

void Server::readyRead() { 
    QTcpSocket *client = (QTcpSocket*) sender(); 

    while (client->canReadLine()) { 
       //here i needed a string.. 
     QString line = QString::fromUtf8(client->readLine()).trimmed(); 
    } 
} 

void Client::readyRead() { 

    // if you need to read the answer of server.. 
    while (this->canReadLine()) { 
    } 
} 

void Client::doConnect() { 
    this->connectToHost(ip_, port_); 
    qDebug() << " INFO : " << QDateTime::currentDateTime() 
      << " : CONNESSIONE..."; 
} 

void Client::connected() { 
    qDebug() << " INFO : " << QDateTime::currentDateTime() << " : CONNESSO a " 
      << ip_ << " e PORTA " << port_; 
    //do stuff if you need 
} 


void Client::sendMessage(const QString& message) { 
    this->write(message.toUtf8()); 
    this->write("\n"); //every message ends with a new line 
} 
관련 문제