QT示例:基于TCP 点对多Socket通讯(server,clients)

本文介绍如何使用QT实现TCP点对多的Socket通讯,重点讲解服务器如何处理多个客户端连接,包括两种处理策略:重写`incomingConnection()`获取SocketDescriptor,或者使用`QTcpSocket`的`peerAddress()`和`peerPort()`获取客户端标识。示例代码涵盖了服务器和客户端的创建及配置。

QT示例:基于TCP 点对多通讯(server,clients)

下载:基于TCP 点对多Socket通讯

一、服务器server

因为对于客户端来说,只能连接一个服务器。而对于服务器来说,它是面向多连接的,如何协调处理多客户端连接就显得尤为重要。

  • 注意问题:
    每个新加入的客户端,服务器给其分配一个SocketDescriptor后,就会emit newConnection()信号,但分配好的SocketDecriptor并没有通过newConnection()信号传递,所以用户得不到这个客户端标识SocketDescriptor。同样的,每当服务器收到新的消息时,客户端会emit readReady()信号,然而readReady()信号也没有传递SocketDescriptor, 这样的话,服务器端即使接收到消息,也不知道这个消息是从哪个客户端发出的。
  • 解决的方法:
  1. 通过重写==[virtual protected] void QTcpServer::incomingConnection(qintptr socketDescriptor)==,获取soketDescriptor。自定义TcpClient类继承QTcpSocket,并将获得的soketDescriptor作为类成员。 这个方法的优点是:可以获取到soketDescriptor,灵活性高。缺点是:需要重写函数、自定义类。
  2. 在newConnection()信号对应的槽函数中,通过QTcpSocket *QTcpServer::nextPendingConnection()函数获取 新连接的客户端:Returns the next pending connection as a connected QTcpSocket object. 虽然仍然得不到soketDescriptor,**但可以通过QTcpSocket类的peerAddress()和peerPort()成员函数获取客户端的IP和端口号,同样是唯一标识。 **优点:无需重写函数和自定义类,代码简洁。缺点:无法获得SocketDecriptor,灵活性差。

本文示例为第二种方法:
1).pro 添加:

QT       += network

2)主函数 main.cpp 添加:

#include "mytcpserver.h"
#include <QApplication>

int main(int argc, char *argv[])
{
   
   
    QApplication a(argc, argv);
    MyTcpServer w;
    w.show();

    return a.exec();
}

3)MyTcpServer.h 添加:

#include "mytcpserver.h"
#include "ui_mytcpserver.h"

MyTcpServer::MyTcpServer(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MyTcpServer)
{
   
   
    ui->setupUi(this);
    //  一 、创建QTcpSever对象;
    tcpServer = new QTcpServer(this);
    ui->edtIP->setText(QNetworkInterface().allAddresses().at(1).toString());   //获取本地IP
    ui->btnConnect->setEnabled(true);
    ui->btnSend->setEnabled(false);
    // 设置默认按钮样式
	ui->btnConnect->setStyleSheet("");

    connect(tcpServer, &QTcpServer::newConnection, this, &MyTcpServer::NewConnectionSlot);
}

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

// 二、监听--断开
void MyTcpServer::on_btnConnect_clicked()
{
   
   
    if(ui->btnConnect->text()=="监听")
    {
   
   
        bool ok = tcpServer->listen(QHostAddress::Any, ui->edtPort->text().toInt());
        if(ok)
        {
   
   
            ui->btnConnect->setText("断开");
            ui->btnConnect->setStyleSheet("color: red;");
            ui->btnSend->setEnabled(true);
        }
    }
    else
    {
   
   
        for(int i=0; i<tcpClient.length(); i++) // 断开所有连接
        {
   
   
            tcpClient[i]-
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值