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); 

相关内容

热门资讯

有玩家发现!aapoker真的... 有玩家发现!aapoker真的假的,aapoker怎么设置提高好牌几率(透视)总结教程(一贯是有挂)...
透视经验!wepoker透视方... 透视经验!wepoker透视方法,wepoker有没有机器人(脚本)有挂教程(其实有挂)-哔哩哔哩1...
透视详细!wpk透视(透视)w... 透视详细!wpk透视(透视)wpk辅助器,教程练习(有挂解密)-哔哩哔哩;1、操作简单,无需wpk辅...
据报道!aapoker怎么选牌... 据报道!aapoker怎么选牌,aapoker怎么提高中牌率(透视)窍门教程(一直是真的挂)-哔哩哔...
透视积累!wepoker代打辅... 透视积累!wepoker代打辅助机器人,wepoker怎么挂飞机(脚本)辅助教程(一直是有挂)-哔哩...
透视必备!wpk私人局辅助是真... 透视必备!wpk私人局辅助是真的吗(透视)wpk辅助器,教程积累(有挂分享)-哔哩哔哩1、wpk私人...
目前来看!aapoker怎么设... 目前来看!aapoker怎么设置抽水,aapoker怎么拿好牌(透视)经验教程(其实真的是有挂)-哔...
透视手册!wejoker黑侠辅... 透视手册!wejoker黑侠辅助器,wejoker辅助软件价格(脚本)必备教程(原来是有挂)-哔哩哔...
透视揭幕!wpk插件(透视)w... 透视揭幕!wpk插件(透视)wpk俱乐部辅助器,教程烘培(有挂助手)-哔哩哔哩1、许多玩家不知道wp...
迎来新发展!aapoker怎么... 迎来新发展!aapoker怎么拿好牌,aapoker俱乐部靠谱吗(透视)烘培教程(总是有挂)-哔哩哔...