QT开发中文网

用套接字实现两个电脑互相发信息 需要几个客户端和服务端

为了实现两个电脑互相发信息,需要使用两个客户端和一个服务器。

一个客户端用于连接服务器并向其发送数据,另一个客户端也用于连接服务器并接收数据。在这种情况下,服务器就起到了转发消息的作用。

因此,需要实现一个TCP服务器和两个TCP客户端,其中一个客户端用于发送消息,另一个客户端用于接收消息。当有一方发送消息时,服务器就会将该消息转发给另一方。

具体步骤如下:

  1. 实现TCP服务器

可以通过继承QTcpServer类来实现TCP服务器。具体代码示例:

class MyTcpServer : public QTcpServer
{
    Q_OBJECT

public:
    explicit MyTcpServer(QObject *parent = nullptr);

protected:
    void incomingConnection(qintptr socketDescriptor) override;

private slots:
    void readData();

private:
    QList<QTcpSocket *> m_clients;
};

MyTcpServer::MyTcpServer(QObject *parent) : QTcpServer(parent)
{
}

void MyTcpServer::incomingConnection(qintptr socketDescriptor)
{
    qDebug() << "New client connected!";

    // 创建新的socket与客户端进行通信
    QTcpSocket *client = new QTcpSocket(this);
    client->setSocketDescriptor(socketDescriptor);

    connect(client, &QTcpSocket::readyRead, this, &MyTcpServer::readData);
    
    // 将新的socket加入到列表中
    m_clients.append(client);
}

void MyTcpServer::readData()
{
    QObject *senderObj = sender();
    
    if (senderObj == nullptr) {
        return;
    }

    QTcpSocket *client = qobject_cast<QTcpSocket *>(senderObj);
    
    if (client == nullptr) {
        return;
    }
    
    // 从客户端读取数据
    QByteArray data = client->readAll();
    
    // 转发给其他客户端
    for (QTcpSocket *otherClient : m_clients) {
        if (otherClient != client && otherClient->state() == QAbstractSocket::ConnectedState) {
            otherClient->write(data);
        }
    }
}

在incomingConnection()函数中,当有新的客户端连接时,就会创建一个新的QTcpSocket对象与其进行通信,并将该socket加入到m_clients列表中。

在readData()函数中,当有客户端发送数据时,服务器就会将该数据转发给所有其他的已连接客户端。

  1. 实现TCP客户端

需要实现两个TCP客户端:一个用于向服务器发送消息,另一个用于接收来自服务器转发的消息。

代码示例:

class MyTcpClient : public QObject
{
    Q_OBJECT

public:
    explicit MyTcpClient(QObject *parent = nullptr);

signals:
    void dataReceived(const QString &data);

public slots:
    void connectToHost(const QString &hostName, quint16 port);
    void sendData(const QString &data);

private slots:
    void readData();

private:
    QTcpSocket *m_socket;
};

MyTcpClient::MyTcpClient(QObject *parent) : QObject(parent)
{
}

void MyTcpClient::connectToHost(const QString &hostName, quint16 port)
{
    m_socket = new QTcpSocket(this);
    
    connect(m_socket, &QTcpSocket::readyRead, this, &MyTcpClient::readData);
    
    m_socket->connectToHost(hostName, port);
}

void MyTcpClient::sendData(const QString &data)
{
    if (m_socket != nullptr && m_socket->state() == QAbstractSocket::ConnectedState) {
        QByteArray bytes = data.toUtf8();
        m_socket->write(bytes);
    }
}

void MyTcpClient::readData()
{
    QObject *senderObj = sender();
    
    if (senderObj == nullptr) {
        return;
    }

    QTcpSocket *socket = qobject_cast<QTcpSocket *>(senderObj);
    
    if (socket == nullptr) {
        return;
    }
    
    // 从服务器接收数据
    QByteArray data = socket->readAll();
    
    // 发送信号通知UI更新
    emit dataReceived(QString(data));
}

其中,一个客户端用于向服务器发送消息,另一个客户端用于接收来自服务器转发的消息。在MyTcpClient类中可以定义一个信号dataReceived(),当有新的数据传入时就会触发该信号。

  1. 在UI中使用TCP客户端

在UI中,可以通过实例化两个MyTcpClient对象来分别作为发送方和接收方。

具体代码示例:

class MainWindow : public QMainWindow
{
public:
    explicit MainWindow(QWidget *parent = nullptr);

private slots:
    void on_sendButton_clicked();
    void onDataReceived(const QString &data);

private:
    Ui::MainWindow *ui;

    MyTcpClient *m_sender;
	MyTcpClient *m_receiver;
};

MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent), ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	m_sender = new MyTcpClient(this);
	connect(m_sender, &MyTcpClient::dataReceived, this, &MainWindow::onDataReceived);

	m_receiver = new MyTcpClient(this);
	connect(m_receiver, &MyTcpClient::dataReceived, this, &MainWindow::onDataReceived);

	// 连接到服务器
	m_sender->connectToHost("127.0.0.1", 1234);
	m_receiver->connectToHost("127.0.0.1", 1234);
}

void MainWindow::on_sendButton_clicked()
{
	QString message = ui->messageEdit->toPlainText();
	m_sender->sendData(message);
}

void MainWindow::onDataReceived(const QString &data)
{
	ui->textBrowser->append(data);
}

在UI中,当用户点击发送按钮时,就会将消息通过m_sender对象发送给服务器。而当有数据传入时,就会通过m_receiver对象来接收数据,并将其显示在UI的textBrowser控件中。

需要注意的是,在实现TCP客户端和服务器时,需要考虑网络延迟、网络异常等情况。因此,在实际应用中需要对异常情况进行处理,以保证程序的稳定性和健壮性。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://qt.0voice.com/?id=2818

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?