当前位置: 首页 > article >正文

Qt笔记:网络编程Tcp

一、铺垫

1.以下只是告诉诸位怎样去构建服务器与客户端;客户端这样构建肯定没问题;但是服务端不可能这样写,因为他是布置在Linux上的,纯数据类处理服务器,根本不可能用Qt写;这在Qt的http类中就表明了;

2.如果客户端不加密;和没穿衣服裸奔是一样的,加密我感觉才只是穿了条裤衩,最起码在奔跑的时候还有点遮挡,到了浴池都要脱(只要学过Linux网络编程,上网感觉就是在裸奔);所以这种方式只能存在于开源项目或者其他一些项目;Tcp的传输是按照字节流的粘包问题也需要程序员去搞定;问题还是蛮多的;

3.Qt不需要Linux的多线程来解决一次只能处理一个链接的问题,但是在多路转接上真实省了太多的脑细胞;而且可以设置定时器;来把超时的连接关掉;真是牛!!!

二、服务端

this->setWindowTitle("服务器");//1.修改窗口标题;
QTcpServer* tcpServer=new QTcpServer(this);//2.创建实例
//3.信号和槽函数连接——当有新链接连上之时,会自动调用函数;connect(tcpServer,&QTcpServer::newConnection,this,&Widget::processConnection);    //4.绑定并监听端口号    //这个操作是最后一步;//绑定并监听
if(!tcpServer->listen(QHostAddress::Any,9090)){                QMessageBox::information(this,"网络提示",tcpServer->errorString()+"绑定监听IP地址和端口号失败");
        exit(1);
        }
}
void Widget::processConnection()
{
//1.通过tcpServer拿到一个socket对象,通过这个对象来和客户端进行通信
//当有连接进来之时,创建一个服务socket;linux来说是一个套接字;    
//peerAddress——对端地址;客户端地址; 
QTcpSocket* clientSocket = tcpServer->nextPendingConnection();    
QString log = "["+clientSocket->peerAddress().toString()+":"+\                            QString::number(clientSocket->peerPort())+"]客户端上线";
ui->listWidget->addItem(log);
//2.通过信号槽来处理客户端发来的请求的情况——使用lamda表达式来写  connect(clientSocket,&QTcpSocket::readyRead,this,[=]()
{        
//1)读取请求数据;此处readAll 返回的是QByteArray 通过赋值转成QString
QString request = clientSocket->readAll();
//2) 根据请求处理响应——此处是回显;就不做处理;
const QString& response =request;
//3)把响应写回客户端
clientSocket->write(response.toUtf8());      
//4)把上述信息记录到日志中
QString log = "["+clientSocket->peerAddress().toString()+":"+\                               QString::number(clientSocket->peerPort())+"] req:"\
                +request+"resp: "+response;
ui->listWidget->addItem(log);
});
//3.通过信号槽处理客户端断开连接的情况connect(clientSocket,&QTcpSocket::disconnected,this,[=](){
        //1)把断开连接的信息通过日志显示出来
        QString log = "["+clientSocket->peerAddress().toString()+":"+\        
        QString::number(clientSocket->peerPort())+"]客户端下线";
        ui->listWidget->addItem(log);       
        //2)手动释放clientSocket——随着服务器的运行,客户端越来越多,如果不是释放,此时累积的clientSocket也会越来越多文件描述符泄露,内存泄漏;       
        //告诉QT,在下一轮事件循环中,再进行上述的销毁操作;       
        clientSocket->deleteLater();
        });

}

 三、客户端

//1.设置窗口标题
this->setWindowTitle("客户端");
//2.创建socket对象实例
socket = new QTcpSocket(this);
//3.和服务器建立连接;调用这个函数,此时系统内核就会和对方的服务器进行三次握手;    
//此处这个函数不会阻塞等待三此握手完毕~(非阻塞函数);
//原生linux API一般来说都是默认阻塞I/O通信的;此时必须要进行阻塞操作;
socket->connectToHost("127.0.0.1",9090);
//4.连接信号槽,去处理响应
connect(socket,&QTcpSocket::readyRead,this,[=](){        
        //读取出响应内容
        QString response = socket->readAll();
        ui->listWidget->addItem("服务器说:" + response);    
});
//5.等待连接建立的结果,确认是否连接成功 
bool ret = socket->waitForConnected();//阻塞函数;判定是否建立连接成功
if(!ret){
        QMessageBox::critical(this,"连接服务器出错",socket->errorString());
        exit(1);
}
void Widget::on_pushButton_clicked()
{
        //1.获取输入框中的内容
        const QString& text=ui->lineEdit->text();
        //2.发送数据给服务器
        socket->write(text.toUtf8());
        //3.把发的消息显示到界面上
        ui->listWidget->addItem("客户端说:"+text);
        //4.清空输入框的内容
        ui->lineEdit->setText("");
}


http://www.kler.cn/a/468544.html

相关文章:

  • 在线机考|2024华为实习秋招春招编程题(最新)——第3题_个性化歌单推荐系统_300分(十一)
  • 回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测
  • 【数据可视化-11】全国大学数据可视化分析
  • 如何查看PostgreSQL的版本
  • [python3]Excel解析库-openpyxl
  • Vue3+Element Plus的表格分页实战
  • 自闭症儿童康复个案研究:深度解析治疗效果
  • C/C++中new/delete与malloc/free的区别及对象管理
  • Hello 2025
  • 《机器学习》从入门到实战——决策树
  • 记录一次电脑被入侵用来挖矿的过程(Trojan、Miner、Hack、turminoob)
  • 算法13、基础二分查找的应用(木根切割等)
  • kubernetes-循序渐进了解coredns
  • 打造三甲医院人工智能矩阵新引擎(二):医学影像大模型篇--“火眼金睛”TransUNet
  • Spring Boot教程之四十九:Spring Boot – MongoRepository 示例
  • 【数据结构与算法:二、线性表】
  • Zookeeper模式安装Kafka(含常规、容器两种安装方式)
  • SpringBoot的6种API请求参数读取方式
  • 【C++】P1428 小鱼比可爱
  • Unity开发2d游戏全套教程[入门案例]
  • 0-基于蚁群优化和带注意力机制的循环神经网络的新型混合算法用于解决旅行商问题(HAL science)(完)
  • 【数据结构与算法:五、树和二叉树】
  • Springboot使用Rabbitmq的延时队列+死信队列实现消息延期消费
  • 快速将索尼手机联系人导出为 HTML 文件
  • 2024 年度时序数据库 IoTDB 论文总结
  • From matplotl1b.path 1mport failed to import ImportError:numpy.core.multiarray