QT 之 TCP 服务端 连接 多客户端 处理学习

    自学QT中, 在此记录一下TCP多链接的方法。

    跟着 “Qt Creator快速入门” 学了一段时间了,刚接触网络编程, 例子中仅仅简单的 用 客户端 连接了一下 服务端, 然后 服务端发送了一条信息就关闭了, 感觉太简单, 无法实际应用到项目中, 于是查找了下资料, 编写了一个多连接的 服务端, 监听本机第一个 ipv4的地址, 端口号固定为 9011,程序做的只是简单的 打印客户端的IP 及数据 , 在收到的数据前面添加几个字符 原路发送回去。客户端就不贴了, 比较简单, 测试可用使用sscom 最新版进行。代码-头文件如下:

#ifndef SERVER_H
#define SERVER_H

#include <QDialog>
#include <QList>

class QTcpServer;
class QTcpSocket;

namespace Ui {
class Server;
}

class Server : public QDialog
{
    Q_OBJECT

public:
    explicit Server(QWidget *parent = 0);
    ~Server();

protected slots:
    void socketRead(void);
private:
    Ui::Server *ui;
    QTcpServer *tcpServer;
    QList<QTcpSocket*> tcpSockets;
private slots:
    void newConnect();

    void deleteSocket();
};

#endif // SERVER_H

代码-c++文件如下:

#include "server.h"
#include "ui_server.h"
#include <QtNetwork>
#include <QList>

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

    QHostAddress addr;    //IPv4地址(可能有多条)
    QHostInfo info   = QHostInfo::fromName(QHostInfo::localHostName());
    qDebug()<<"IP Addr:"<< info.addresses();
    foreach(QHostAddress address, info.addresses())
    {
        if(address.protocol() == QAbstractSocket::IPv4Protocol)
        {
            addr = address;  //   qDebug() <<"IPv4 addr: "<< address.toString();
            ui->label->setText("Listen:" +address.toString() + ":9011");
            break;
        }
    }

    tcpServer = new QTcpServer(this);    //QHostAddress("127.0.0.1")
    if (!tcpServer->listen(addr, 9011))
    {
        qDebug() << tcpServer->errorString();
        close();
    }
    connect(tcpServer, &QTcpServer::newConnection,
            this, &Server::newConnect);
}

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

void Server::newConnect()
{
    // 获取已经建立的连接的套接字
    QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
    // 放入 QList
    tcpSockets.append(clientConnection);
    ui->textBrowser->append("NewClient:" + clientConnection->peerAddress().toString());
    // 数据就绪信号 到 自定义 读槽函数
    QObject::connect(clientConnection, &QTcpSocket::readyRead, this, &Server::socketRead);
    // 断开连接后 从QList中删除, 并删除套接字
    connect(clientConnection, &QTcpSocket::disconnected, this, &Server::deleteSocket);
    qDebug()<<"cli Num:"<<tcpSockets.size()<<endl;
}

void Server::deleteSocket(void)
{
    int i = 0;
    foreach(QTcpSocket* soc, tcpSockets)
    {
        if(soc->state() == QTcpSocket::UnconnectedState)
        {
            qDebug()<<soc->peerAddress().toString()<<"closed"<<endl;
            soc->deleteLater();
            tcpSockets.removeAt(i); //tcpSockets.removeOne(soc);
        }
        i++;
        qDebug()<<"i:"<<i<<endl;
    }
}


void Server::socketRead(void)
{
    QByteArray  strs, block;

    foreach(QTcpSocket* soc, tcpSockets)
    {
        if(soc->bytesAvailable() > 0)
        {
            strs = soc->readAll();
            strs.insert(0, QString("S rec:"));
            soc->write(strs);
        }

    }
    ui->textBrowser->append("recNum:"+QString::number(strs.size()-6));
    ui->textBrowser->append(strs);
}

server.ui 文件内容如下

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Server</class>
 <widget class="QDialog" name="Server">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>412</width>
    <height>433</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Server</string>
  </property>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>30</y>
     <width>201</width>
     <height>31</height>
    </rect>
   </property>
   <property name="text">
    <string>等待连接!</string>
   </property>
  </widget>
  <widget class="QTextBrowser" name="textBrowser">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>80</y>
     <width>381</width>
     <height>331</height>
    </rect>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

截图:

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值