繁体   English   中英

Qt双向客户端服务器使用QTcpSocket和QTcpServer

[英]Qt bidirectional client server using QTcpSocket and QTcpServer

我正在尝试实现双向客户端 - 服务器程序,其中客户端和服务器可以在彼此之间传递序列化对象。 我试图使用Qt(QTcpSocket和QTcpServer)来做到这一点。 我在java中实现了这样的程序,但是我无法弄清楚如何使用Qt来实现它。 我查看了财富客户端财富服务器示例......但是从我所看到的,客户端只是发信号通知服务器,服务器向它发送一些数据。 我需要客户端和服务器来回发送对象。 我不是在寻找一个完整的解决方案,我正在寻找的是一些正确方向的指导。

我写了一些代码,它接受连接但不接受数据。

服务器

这个类是服务器; 它应该接受连接并输出正在发送的缓冲区的大小。 但它输出0

#include "comms.h"

Comms::Comms(QString hostIP, quint16 hostPort)
{
    server = new QTcpServer(this);
    hostAddress.setAddress(hostIP);
    this->hostPort = hostPort;


}

void Comms::attemptConnection(){
    connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted()));
    //socket = server->nextPendingConnection();
    server->listen(hostAddress,hostPort);
    //receivedData = socket->readAll();
}

void Comms::connectionAccepted(){
    qDebug()<<"Connected";
    socket = new QTcpSocket(server->nextPendingConnection());

    char* rec = new char[socket->readBufferSize()];
    qDebug()<<socket->readBufferSize();
}

客户

这个类是客户端。 应该发送字符串'hello'。 它成功发送(据我所知)

#include "toplevelcomms.h"
#include "stdio.h"

TopLevelComms::TopLevelComms(QString hostIP, quint16 hostPort)
{
    tcpSocket = new QTcpSocket();
    hostAddress.setAddress(hostIP);
    this->hostPort = hostPort;
}


void TopLevelComms::connect(){
    tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite);
    //tcpSocket->waitForConnected(1);

    QString string = "Hello";
    QByteArray array;
    array.append(string);
    qDebug()<<tcpSocket->write(array);
}

请告诉我我做错了什么,或者告诉我在Qt中建立我想要的东西的一般逻辑。

QTcpSocket默认是异步的,所以当你调用connectToHost并在同一个上下文中写入时,它不会被发送,因为套接字没有连接。 您应该更改“客户”代码:

void TopLevelComms::connect(){
    tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite);
    if(tcpSocket->waitForConnected()) // putting 1 as parameter isn't reasonable, using default 3000ms value
    {
        QString string = "Hello";
        QByteArray array;
        array.append(string);
        qDebug()<<tcpSocket->write(array);
    }
    else
    {
        qDebug() << "couldn't connect";
    }
}

注意:你也没有检查你是否能听

void Comms::attemptConnection(){
    connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted()));
    //socket = server->nextPendingConnection();

    if(server->listen(hostAddress,hostPort))
    {
        qDebug() << "Server listening";
    }
    else
    {
        qDebug() << "Couldn't listen to port" << server->serverPort() << ":" << server->errorString();
    }
    //receivedData = socket->readAll();
}

最后一件事。 请注意,QTcpServer :: nextPendingConnection()返回QTcpSocket,因此您不是创建新连接,而是创建具有nextPendingConnection作为父级的新QTcpSocket

void Comms::connectionAccepted(){
    qDebug()<<"Connected";
    // WRONG! it will use QTcpSocket::QTcpSocket(QObject * parent)
    //socket = new QTcpSocket(server->nextPendingConnection());
    // use simple asign
    socket = server->nextPendingConnection();
    // move reading to slot
    connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
}

现在我们将把阅读移到单独的插槽中

void Comms::readSocket()
{
    // note that dynamic size array is incompatible with some compilers
    // we will use Qt data structure for that
    //char* rec = new char[socket->readBufferSize()];
    qDebug()<<socket->readBufferSize();
    // note that QByteArray can be casted to char * and const char *
    QByteArray data = socket->readAll();
}

我必须承认,对于这样的小代码示例来说,这是一个很多错误。 您需要了解有关TCP / IP连接的一些知识。 这些是流,并且不保证整个数据块会立即到达您

看起来你有时间问题。 由于您的客户端和服务器是不同的进程,因此在服务器的connectionAccepted()函数尝试从套接字读取之前,您无法保证正在执行整个TopLevelComms::connect() (以及网络数据传输)。

我怀疑如果你利用QTcpSocket的waitForReadyRead()函数,你应该有更好的运气:

void Comms::connectionAccepted(){
    qDebug()<<"Connected";
    socket = new QTcpSocket(server->nextPendingConnection());

    if( socket->waitForReadyRead() ) {
        char* rec = new char[socket->readBufferSize()];
        qDebug()<<socket->readBufferSize();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM