自学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>
截图: