QT TCP服务器
创始人
2025-01-17 07:02:36
0次

客户端:

功能:

连接:获取ip地址和端口号,并连接   取消:关闭窗口

工程文件加上

QT=+=core gui network

相关类与函数

QTcpSocket类:(需要被包含)

connectToHost()  连接。参数:QHostAdress地址对象(可用QString初始化),端口号(16位短整型)(QString自带进制转换,如ip.toshort)

连接成功后会发出一个信号:&QTcpSocket::connected

连接异常也会发出一个信号:&QTcpSocket::disconnected

peerAddress();获取客户端地址

peerAddress的子函数toString():将其转化位字符串

peerPort():获取客户端端口号(并非服务器端口)

write():参数:QByteArray ,可用append拼接,发送后会出现&QTcpSocket::readyread信号

QHostAddress类:(需要被包含)

其他函数:

(QTcpSocket * )sender();获取信号的发送者并强制转为QTcpSocket指针

服务器:

相关类与函数:

QTcpServer类:

listen():监听网卡,参数QHostAdress::AnyIPv4,端口号

如果有信号,会发出QTcpServer::newConnection信号

nextPendingConnection() 建立TCP连接,返回QTcpSocket类型

实现服务器与客户端连接

在widget构造函数中监听网卡ip,等待请求,收到信号后与客户端建立连接

注意,必须使用127开头的地址

127.0.0.1 地址称为本地回环地址,是一种特殊的网络地址,用于让单独的计算机进行自我回路测试和通信。 这个地址在 IP 协议中被定义为环回地址。 在网络设备中,网络接口上的 127.0.0.1 地址本质上是本机对自己的网络地址。

通信

打开其他窗口:新建qt->设计师...,在客户端创建新的窗口类chat

this->hide()隐藏窗口

创建新窗口对象时要用堆空间创建,也即是指针形式,这样申请的内存不会被销毁,

widget在连接成功后隐藏当前窗口,并打开新窗口chat,与打开widget窗口类似

         chat *k=new chat(SOCKET);          k->show();

要将socket信息传到新窗口中,所以类chat中要有参数,并在chat构造函数中初始化

QTcpSocket *s

在新窗口中,使用socket中的write发送信息,参数是QByteArray类型

在服务器中连接后再connect一个新的信号与曹:

&QTcpSocket::readyRead &Widget::data_resslot

在槽函数中要注意变量的范围,如果QTcpSocket指针是内部变量,则需要使用

(QTcpSocket*)sender();

将其转化为QTcpSocket类型指针,再用readAll读取所有发送的数据。

服务器代码:

chat.h

#ifndef CHAT_H #define CHAT_H  #include  #include    namespace Ui { class chat; }  class chat : public QWidget {     Q_OBJECT  public:     explicit chat(QTcpSocket *s,QWidget *parent = nullptr);     ~chat();  private slots:     void on_clearButton_clicked();      void on_sendButton_2_clicked();  private:     Ui::chat *ui;     QTcpSocket *SOCKET; };  #endif // CHAT_H 

widget.h

#ifndef WIDGET_H #define WIDGET_H  #include  #include  #include  #include  #include  #include   QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE  class Widget : public QWidget {     Q_OBJECT  public:     Widget(QWidget *parent = nullptr);     ~Widget();   private slots:     void on_cancelButton_2_clicked();      void on_connectButton_clicked();      void on_pushButton_clicked();  private:     Ui::Widget *ui;     QTcpSocket *SOCKET; }; #endif // WIDGET_H 

chat.cpp

#include "chat.h" #include "ui_chat.h"  chat::chat(QTcpSocket *s,QWidget *parent) :     QWidget(parent),     ui(new Ui::chat) {     ui->setupUi(this);     SOCKET=s; }  chat::~chat() {     delete ui; }  void chat::on_clearButton_clicked() {     ui->lineEdit->clear(); }  void chat::on_sendButton_2_clicked() {     QString text1=ui->lineEdit->text();     QByteArray ba;     ba.append(text1);     //write只能发送QByteArray类型数据     SOCKET->write(ba); } 

widget.cpp

#include "widget.h" #include "ui_widget.h"  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);     SOCKET=new QTcpSocket;     //成功/异常警告     connect(SOCKET,&QTcpSocket::connected,[this]()     {          QMessageBox::information(this,"提示","连接成功");          this->hide();          chat *k=new chat(SOCKET);          k->show();     });     connect(SOCKET,&QTcpSocket::disconnected,[this]()     {          QMessageBox::warning(this,"警告","连接异常");     });  }  Widget::~Widget() {     delete ui; }   void Widget::on_cancelButton_2_clicked() {     this->close(); }  void Widget::on_connectButton_clicked() {     //获取ip与端口号     QString com1=ui->COMlineEdit_2->text();     QString ip1=ui->IPlineEdit->text();     if(com1.isEmpty()||ip1.isEmpty())     {         QMessageBox::warning(this,"警告","请输入ip地址和端口号");     }     //开始连接     SOCKET->abort();     SOCKET->connectToHost(QHostAddress(ip1),com1.toShort()); }  void Widget::on_pushButton_clicked() {     qDebug()<<"disconnect";     SOCKET->disconnectFromHost(); } 

服务器代码:

widget.h

#ifndef WIDGET_H #define WIDGET_H  #include  #include  #include  #include  #include  #include    QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE #define TCPCOM 8000    class Widget : public QWidget {     Q_OBJECT  public:     Widget(QWidget *parent = nullptr);     ~Widget();  private slots:     void serverslot();     void on_check_clicked();     void data_resslot(); private:     Ui::Widget *ui;     QTcpServer *SERVER; }; #endif // WIDGET_H 

widget.cpp

#include "widget.h" #include "ui_widget.h"  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);     SERVER=new QTcpServer;     SERVER->listen(QHostAddress::Any,TCPCOM);     qDebug()<nextPendingConnection();     QHostAddress ip1=SOCKET1->peerAddress();     quint16 com1=SOCKET1->peerPort();     ui->comlineEdit->setText(QString::number(com1));     ui->iplineEdit_2->setText(ip1.toString());     QMessageBox::information(this,"提示","连接成功");     connect(SOCKET1,&QTcpSocket::readyRead,this,&Widget::data_resslot); }     void Widget::on_check_clicked() {     if(SERVER->isListening())     {             qDebug()<<"IS LISTENING";     }  } void Widget::data_resslot() {     QTcpSocket *Socket=(QTcpSocket*)sender();     ui->datalineEdit->setText(Socket->readAll());  } 

结果:

多线程

在服务器中启用多线程,即可接收多个客户端的连接。

相关类与函数

在文件中添加c++类,在继承中继承QThread,添加后多了.h和.cpp文件

QThread类,需要包含

start()打开线程

虚函数run():在run里连接信号与槽,线程处理函数

自定义信号

在类中定义,和private同级,在信号传递时可以附加参数

signals:  void sendtowidget(QByteArray ba);

在需要发出信号的地方加上即可,最后在widget中连接信号与槽

QByteArray ba=socket->readall(); emit sendtowidget(ba); 

相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...