如何使用QTcpSocket在Qt中监听特定端口?

4

我使用QTcpSocket来在两个应用之间进行通信,一个是C++程序,另一个是用PHP编写的网页。

目标是使用socket从我的网页向C++程序发送数据。

我不知道如何在特定端口(例如12345)上打开连接并侦听是否有数据传输。

到目前为止,我已经编写了以下代码:

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Mysocket = new QSocket(this);
    Mysocket->Initialization();
}

MainWindow::~MainWindow()
{
    delete ui;
}

QSocket.cpp

#include "qsocket.h"
#define SOCKET_PORT 12345
QSocket::QSocket(QObject *parent) :
    QObject(parent)
{
}


void QSocket::Initialization()
{
    //connected
    socket = new QTcpSocket(this);
    socket->connectToHost("localhost",SOCKET_PORT);
    connect(socket,SIGNAL(connected()),this,SLOT(connected()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
    connect(socket,SIGNAL(bytesWritten(qint64)),this,SLOT(bytesWritten(qint64)));
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    if(!socket->waitForConnected(1000))
    {
        QMessageBox::StandardButton reply;
        reply = QMessageBox::question(0,"Error","Error in Socket Connection",
                                        QMessageBox::Yes|QMessageBox::No);
        socket->close();
    }
    socket80->close();
}
void QSocket::connected()
{
        QMessageBox::StandardButton reply;
        int PortNumber = socket->localPort();
        reply = QMessageBox::question(0,"Connected","Socket Connection is Established",
                                        QMessageBox::Yes|QMessageBox::No);

        qDebug()<<"I'm Listening to Port: "<<PortNumber<<"on the local host \n";
}

void QSocket::disconnected()
{
    qDebug()<<"Disconnected .... \n";
    socket->close();
}

void QSocket::bytesWritten(qint64 bytes)
{
        qDebug()<<"We wrote "<<bytes<<" \n";
}

void QSocket::readyRead()
{
    qDebug()<<"Reading .... \n";
    qDebug()<<socket->bytesAvailable();
    qDebug()<<socket->readAll();
}

当我运行这段代码时,它没有打开任何连接,并且报错并进入了这个if语句..
if(!socket->waitForConnected(1000))
{
    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(0,"Error","Error in Socket Connection",
                                    QMessageBox::Yes|QMessageBox::No);
    socket->close();
}

如果我将端口号更改为80,则一切正常,所有功能都能正常工作。通过阅读SO上的一些帖子,我意识到一个解决方法是使用QTcpServer,但我没有任何具体的经验。问题出在哪里?!
P.S.
我的平台规格。
Ubuntu 13.10
Qt 5.2.1

1
我认为你需要使用 QTcpServer 及其 QTcpServer::listen() 函数。一旦有新的连接,就会发出 newConnection 信号,你需要处理它以创建一个新的套接字进行数据传输。 - vahancho
1个回答

6
你可以使用以下示例服务器。只需要调用 start_listen(int port_no) 即可在端口上开始监听。
#include <QtNetwork>
#include <QMessageBox>

class server : public QTcpServer {
    Q_OBJECT
public:
    explicit server(QObject *parent = 0);
    ~server();
    QTcpSocket server_socket;
public slots:
    void tcpReady();
    void tcpError( QAbstractSocket::SocketError error );
    bool start_listen(int port_no);
protected:
    void incomingConnection( int descriptor );
};

server::server(QObject *parent) : QTcpServer(parent) {
    connect( &server_socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(tcpError(QAbstractSocket::SocketError)) );
    connect( &server_socket, SIGNAL(readyRead()),
             this, SLOT(tcpReady()) );
    server_socket.setSocketOption(QAbstractSocket::KeepAliveOption, true );
}

server::~server() {
    server_socket.disconnectFromHost();
    server_socket.waitForDisconnected();
}

void server::tcpReady() {
    QByteArray array = server_socket.read(erver_socket.bytesAvailable());
}

void server::tcpError(QAbstractSocket::SocketError error) {
    QMessageBox::warning( (QWidget *)this->parent(), tr("Error"),tr("TCP error: %1").arg( server_socket.errorString() ) );
}

bool server::start_listen(int port_no) {
    if( !this->listen( QHostAddress::Any, port_no ) ) {
        QMessageBox::warning( (QWidget *)this->parent(), tr("Error!"), tr("Cannot listen to port %1").arg(port_no) );
    }
    else
        return true;
}

void server::incomingConnection(int descriptor) {
    if( !server_socket.setSocketDescriptor( descriptor ) ) {
        QMessageBox::warning( (QWidget *)this->parent(), tr("Error!"), tr("Socket error!") );
        return;
    }
}

谢谢你的回答。我还没有测试你的代码,但在监听端口之前是否有必要打开端口上的连接?一般来说我们可以监听任何端口吗?还是我需要在我的C++程序中打开该端口才能使用它? - PsP
如果答案是肯定的,那么怎么做呢?我该如何在Qt中为QTcpServer对象打开一个端口? - PsP
通过调用 listen 函数,实际上是在打开一个端口并监听它来等待别人连接。当有人连接时,将调用 incomingConnection 函数,并通过调用 setSocketDescriptor 并传递描述符来建立连接,在此之后你可以通过 QTCPSocket 进行通信。 - Nejat
还有一件事..如果我使用listen方法启动连接,我是否必须在获取任何内容之前向客户端发送一些内容,或者不需要这样做?在qtcpserver中编写端口的特定函数是什么? - PsP
当您调用listen时,应等待客户端连接您,这将调用incomingConnection。要编写数据,您应该使用QTcpSocket对象的write方法,例如:server_socket.write(someBytes); - Nejat
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接