QT编写TCP服务器通信总结: TCP服务器通信 , QT提供了服务器类QTcpServer和客户端类QTcpSocket
程序源码下载:https://download.csdn.net/download/dianzishi123/10849989
说明:上传的源码是最初始的,文档下的源码会根据不同时候的不同理解而改动
操作流程:
1. 创建一个基于MainWindows的UI工程,在工程管理文件(.pro文件)中添加 network 模块 ,并设置UI界面
2. 使用QTcpServer类创建一个TCP服务器对象并获取主机IP
3. 监听端口, 并设置最大监听数量
4. 信号和槽的处理(信号:新连接; 客户端连入信号; 读取客户端数据信号; 客户端断开信号等)
步骤1:
(1). 工程目录:
(2). 在Server.pro文件中添加network模块
(3). UI界面
(4) . 改变使用的对象名称(就是变量名,不使用默认的);选中要改变的控件,点击鼠标右键选择"改变对象名称..."
(5). 有两个槽函数不用自己手动连接(打开服务器和发送的槽函数)
选择"打开服务器" 或 "发送"控件点击鼠标右键选择 "转到槽..."
设置完UI界面下面开始编写控制程序
mainwindow.cpp文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setMaximumSize(460,268);//设置固定界面大小
setMinimumSize(460,268);
Init();
}
MainWindow::~MainWindow()
{
delete ui;
}
QString MainWindow::getHostIpAddrs() //获取本机IP地址
{
QString ip;
QList ipAddrs = QNetworkInterface::allAddresses();
for (int i = 0; i < ipAddrs.size(); ++i)
{
if (ipAddrs.at(i) != QHostAddress::LocalHost && ipAddrs.at(i).toIPv4Address())
{
// 如果这个地址不是127.0.0.1,并且是IPv4的地址,就将其赋值给ip,并结束for循环
ip = ipAddrs.at(i).toString();
break;
}
}
// 如果ip为空,则将其赋值为127.0.0.1
if (ip.isEmpty())
ip = QHostAddress(QHostAddress::LocalHost).toString();
return ip;
}
//初始化函数
void MainWindow::Init()
{
// 1.创建一个服务器
tcpServer = new QTcpServer(this);
// 2.获取网卡信息
QString ipAddr = getHostIpAddrs();
ui->SerPort_Edit->setText("8080");//打开时设置默认端口
ui->SerIP_Edit->setText(ipAddr);//把获取的服务器IP填到对应的IP 行
//设置打开服务器按钮的背景颜色
pal=ui->openButton->palette();
pal.setColor(QPalette::Button,Qt::cyan);
ui->openButton->setPalette(pal);
ui->openButton->setAutoFillBackground(true);
ui->openButton->setFlat(true);
}
//开启TCP服务器按钮
void MainWindow::on_openButton_clicked()
{
// 1. 开启服务监听端口
QString serIP = ui->SerIP_Edit->text();//获取IP
QString serPort = ui->SerPort_Edit->text();//获取端口
bool ret;
if(ui->openButton->text()=="打开服务器") //打开TCP服务
{
ret = tcpServer->listen(QHostAddress(serIP),serPort.toInt());
if(!ret)//服务器打开失败
{
ui->receText->append("未打开TCP服务!");//追加显示
return;
}
ui->receText->append("成功打开TCP服务!");
ui->openButton->setText("关闭服务器");
tcpServer->setMaxPendingConnections(100);//设置最大连接数量
}
else if(ui->openButton->text()=="关闭服务器") //关闭TCP服务
{
ui->receText->append("成功关闭TCP服务!");
ui->openButton->setText("打开服务器");
tcpServer->close();
}
connect(tcpServer,SIGNAL(newConnection()),
this,SLOT(doProcessNewConnect()));//新连接信号和槽
connect(tcpServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));//接收错误处理槽
}
//接收错误信息处理
void MainWindow::doProcessAcceptError(QAbstractSocket::SocketError)
{
}
//新客户端连接槽函数
void MainWindow::doProcessNewConnect()
{
client = tcpServer->nextPendingConnection();//获取客户端描述符
clients.append(client);//获取所有的客户端连接
//读取信息
connect(client,SIGNAL(readyRead()),
this,SLOT(doProcessReadyRead()));//客户端读取内容信号连接槽
connect(client,SIGNAL(disconnected()),
this,SLOT(doProcessDisconnected()));//客户端断开连接信号和槽
//客户端的连入
connect(client,SIGNAL(connected()),
this,SLOT(doProcessConnected()));
}
//客户端读取信息
void MainWindow::doProcessReadyRead()
{
client = (QTcpSocket *)this->sender();
QString str1 = QString("客户端[%1:%2]说:").arg(client->peerAddress().toString())
.arg(client->peerPort());
QString str2;
while(!client->atEnd())//没有读到末尾一直读
{
str2.append(QString(client->readAll()));
qDebug()<<"hhhhhhhhhh"<receText->append(msg);
}
//客户端断开连接
void MainWindow::doProcessDisconnected()
{
client = (QTcpSocket *)this->sender();
QString msg = QString("客户端[%1:%2]退出!").arg(client->peerAddress().toString()).arg(client->peerPort());
ui->receText->append(msg);
//删除断开的客户端
for(int i=0;ipeerAddress()==client->peerAddress())
{
if(clients.at(i)->peerPort()==client->peerPort())
{
clients.removeAt(i);
break;
}
}
}
}
//发送按钮
void MainWindow::on_sendButton_clicked()
{
QString clientIp = ui->clientIpEdit->text();//获取客户端IP
QString clientPort = ui->clientPortEdit->text();//获取客户端端口
for(int i=0;ipeerAddress().toString()==clientIp)
{
if(clients.at(i)->peerPort()==clientPort.toUInt())
{
QString msg = ui->sendLineEdit->text();
clients.at(i)->write(msg.toLatin1());
break;
}
}
}
}
void MainWindow::doProcessConnected()
{
client = (QTcpSocket *)this->sender();
QString msg = QString("客户端[%1:%2]连入:")
.arg(client->peerAddress().toString())
.arg(client->peerPort());
ui->receText->append(msg);
}
mainwindow.h文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_openButton_clicked();//打开服务器点击按钮槽函数
void on_sendButton_clicked();//发送按钮点击槽函数
//处理客户端连接断开发送数据等槽函数
void doProcessNewConnect();
void doProcessAcceptError(QAbstractSocket::SocketError);
void doProcessDisconnected();
void doProcessReadyRead();
void doProcessConnected();
private:
Ui::MainWindow *ui;
void Init();//初始化函数
QString getHostIpAddrs();//获取本机IP
QPalette pal;//设置按钮背景颜色
QTcpServer *tcpServer;//定义一个TCP服务器
QListclients; //定义连接的客户端
QTcpSocket *client;
};
#endif // MAINWINDOW_H
main.cpp文件:
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}