QTday05(TCP的服务端客户端通信)

这篇具有很好参考价值的文章主要介绍了QTday05(TCP的服务端客户端通信)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现聊天室功能

服务端代码:

pro文件需要导入  network

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>//服务端
#include <QTcpSocket>//客户端
#include <QList>
#include <QMessageBox>
#include <QDebug>

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_startBtn_clicked();
public slots:
    void newConnectSlot();//建立连接的槽函数
    void readyReadSlot();//接收消息的槽函数

private:
    Ui::Widget *ui;

    //实例化服务器对象
    QTcpServer *server;
    //创建存放客户端信息的容器
    QList<QTcpSocket *> socketList;
};
#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(this);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_startBtn_clicked()
{
    //监听任意ip的指定端口
    bool listen_res=server->listen(QHostAddress::Any,ui->portLine->text().toUInt());
    if(listen_res){
        //监听成功
        QMessageBox::information(this,"提示","设置监听成功",QMessageBox::Ok);

    }else{
        //监听失败
        QMessageBox::information(this,"提示","设置监听失败",QMessageBox::Ok);
        return;
    }
    //等待连接
    connect(server,&QTcpServer::newConnection,this,&Widget::newConnectSlot);
}

void Widget::newConnectSlot()
{
    //接收到newConnect信号之后的槽函数,处理接下来的操作

    //获取客户端的套接字,加入容器
    QTcpSocket *s=server->nextPendingConnection();
    socketList.push_back(s);
    qDebug() << "有新客户连接" << s->peerName() << ";" << s->peerAddress().toString() << ":" << QString::number(s->peerPort()) <<endl;
    //此时如果客户端向服务器发送数据,客户端会发送一个readyRead信号
    connect(s,&QTcpSocket::readyRead,this,&Widget::readyReadSlot);
}

void Widget::readyReadSlot()
{
    //客户端有数据发送,触发改槽函数
    //遍历容器,移除无效客户端,接收有效客户端消息
    for (int i=0;i<socketList.count();i++) {
        //如果是非链接状态就移除
        if(socketList.at(i)->state()==QAbstractSocket::UnconnectedState){
            socketList.removeAt(i);
        }
    }
    for (int i=0;i<socketList.count();i++) {
        //如果有字节,就读取并放到ui界面
        if(socketList.at(i)->bytesAvailable()){
            QByteArray msg=socketList.at(i)->readAll();
            QString msgInfo=socketList.at(i)->peerAddress().toString()+":"+QString::number(socketList.at(i)->peerPort())+":"+QString::fromLocal8Bit(msg);
            ui->listWidget->addItem(msgInfo);
            for (int j=0;j<socketList.count();j++) {
                socketList.at(j)->write(msg);
            }
        }
    }
}

ui:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

客户端代码:

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtDebug>
#include <QMessageBox>
#include <QTcpSocket>

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

    void on_disconnectBtn_clicked();

    void on_sendBtn_clicked();

public slots:
    void connnectedSlot();
    void readyReadSlot();
    void disconnectedSlot();

private:
    Ui::Widget *ui;

    //实例化客户端
    QTcpSocket *socket;
    //定义全局变量存储用户名
    QString username;
};
#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);
    //实例化客户端
    socket=new QTcpSocket(this);
    //将发送和断开连接 的按钮默认设置不可用
    ui->sendBtn->setDisabled(true);
    ui->disconnectBtn->setDisabled(true);

    ui->accoutLine->setText("张三");
    ui->ipLine->setText("192.168.125.77");
    ui->portLine->setText("8888");
    //连接成功会触发connected信号,只需要一次
    connect(socket,&QTcpSocket::connected,this,&Widget::connnectedSlot);

    //收信号
    connect(socket,&QTcpSocket::readyRead,this,&Widget::readyReadSlot);

    connect(socket,&QTcpSocket::disconnected,this,&Widget::disconnectedSlot);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_connnectBtn_clicked()
{
    //连接服务器
    username=ui->accoutLine->text();
    QString ip=ui->ipLine->text();
    quint16 port=ui->portLine->text().toUInt();
    socket->connectToHost(ip,port);
    //判断是否连接成功:连接成功后,户端会自动发射一个connected信号,

}

void Widget::connnectedSlot()
{
    QMessageBox::information(this,"提示","连接成功");

    QString msg=username+"进入聊天室";
    socket->write(msg.toLocal8Bit());

    ui->sendBtn->setDisabled(false);
    ui->connnectBtn->setDisabled(true);
    ui->disconnectBtn->setDisabled(false);

}

void Widget::on_disconnectBtn_clicked()
{

    QString msg=username+"离开聊天室";
    socket->write(msg.toLocal8Bit());
    socket->disconnectFromHost();

}

void Widget::on_sendBtn_clicked()
{
    if(ui->infoLine->text().isEmpty()){
        QMessageBox::information(this,"提示","发送的消息不能为空");
        return;
    }
    QString msg=ui->infoLine->text();
    socket->write(msg.toLocal8Bit());
    ui->infoLine->setText("");
}
void Widget::readyReadSlot(){
    QByteArray msg=socket->readAll();

    ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}

void Widget::disconnectedSlot()
{
    ui->sendBtn->setDisabled(true);
    ui->disconnectBtn->setDisabled(true);
    ui->connnectBtn->setDisabled(false);
    QMessageBox::information(this,"提示","断开连接成功");
}

ui:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

运行结果:客户端连接之后可以成功发送信息

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

今日思维导图:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

将聊天功能加入到仿qq登录之后:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

代码:

page2.h:

#ifndef PAGE2_H
#define PAGE2_H

#include <QWidget>
#include <QMovie>
#include <QTcpSocket>
#include <QMessageBox>
#include <QDebug>
#define PORT 8888
#define IP "192.168.125.77"

namespace Ui {
class Page2;
}

class Page2 : public QWidget
{
    Q_OBJECT

public:
    explicit Page2(QWidget *parent = nullptr);
    ~Page2();
public slots:
    void login_slot();
    void connectedSlot();
    void readyReadSlot();
private slots:
    void on_sendBtn_clicked();

private:
    Ui::Page2 *ui;

    QTcpSocket *socket;

};

#endif // PAGE2_H

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMovie>
#include <QMessageBox>
#include <QDebug>
#include <QMouseEvent>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

public slots:
    void loginButton_slot();


signals:
    void login_signal();

private:
    Ui::Widget *ui;

    QPoint p;//定义全局变量p,记录位置
public:
    static QString username;
};

#endif // WIDGET_H

main.cpp:

#include "widget.h"
#include "page2.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    Page2 p2;
    QObject::connect(&w,&Widget::login_signal,&p2,&Page2::login_slot);
    return a.exec();
}

page2.cpp:

#include "page2.h"
#include "widget.h"
#include "ui_page2.h"

Page2::Page2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Page2)
{
    ui->setupUi(this);
    QMovie *movie = new QMovie(":/111/cai.gif");
    ui->label->setMovie(movie);
    ui->label->setScaledContents(true);
    movie->start();
    //实例化客户端
    socket=new QTcpSocket(this);
    qDebug() << "实例化客户端";
    //建立connected信号和指定槽函数的连接
    connect(socket,&QTcpSocket::connected,this,&Page2::connectedSlot);
    //建立readyRead信号和指定槽函数连接
    connect(socket,&QTcpSocket::readyRead,this,&Page2::readyReadSlot);

}

Page2::~Page2()
{
    delete ui;
}

void Page2::login_slot()
{
    qDebug() << "登录按钮";
    this->show();
    //连接客户端
    socket->connectToHost(IP,PORT);
}

void Page2::connectedSlot()
{
    //连接成功后触发该槽函数
    qDebug() << "连接成功";
    QMessageBox::information(this,"提示","连接成功");

    QString msg=Widget::username+"加入了聊天";
    socket->write(msg.toLocal8Bit());
}

void Page2::readyReadSlot()
{
    //收到服务端发送的消息时触发该槽函数
    QByteArray msg=socket->readAll();
    ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}

void Page2::on_sendBtn_clicked()
{
    if(ui->infoEdit->toPlainText().isEmpty()){
        QMessageBox::information(this,"提示","发送的消息不能为空");
        return;
    }
    QString msg=ui->infoEdit->toPlainText();
    socket->write(msg.toLocal8Bit());
    ui->infoEdit->clear();
}

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
QString Widget::username="";
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setFixedSize(560,430);
    this->setStyleSheet("background-color:#faf7ec");
    this->setWindowFlag(Qt::FramelessWindowHint);//无边框
    QMovie *movie = new QMovie(":/111/cai.gif");
    ui->backLabel->setMovie(movie);
    ui->backLabel->setScaledContents(true);
    movie->start();

    ui->closeButton->setStyleSheet("border-image:url(:/111/basketball.png)");


    ui->avatorLabel->resize(60,60);
    ui->avatorLabel->setStyleSheet("border-image:url(:/111/user.png);border-radius:30px");

    ui->accountLabel->setPixmap(QPixmap(":/111/account.jpg"));
    //ui->accountLabel->resize(40,40);
    ui->accountLabel->setScaledContents(true);

    ui->passwdLabel->setPixmap(QPixmap(":/111/passwd.jpg"));
    //ui->passwdLabel->resize(40,40);
    ui->passwdLabel->setScaledContents(true);

    ui->accoountLine->setPlaceholderText("账号");
    ui->passwdLine->setPlaceholderText("密码");
    ui->passwdLine->setEchoMode(QLineEdit::Password);

    ui->loginLabel->setPixmap(QPixmap(":/111/2.png"));
    ui->loginLabel->setScaledContents(true);

    ui->loginButton->setStyleSheet("background-color:#409EFF;border-radius:5px");

    connect(ui->closeButton,SIGNAL(clicked()),this,SLOT(close()));

    connect(ui->loginButton,&QPushButton::clicked,this,&Widget::loginButton_slot);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::loginButton_slot()
{
    //判断用户账号密码的正确性
    if(ui->accoountLine->text()=="admin"&&ui->passwdLine->text()=="123456"){
        username="admin";
        qDebug() << "登录成功" <<endl;
        QMessageBox::information(this,"提示","登录成功",QMessageBox::Ok);
        this->close();
        //开启新窗口,手动触发信号
        emit login_signal();
    }else{
        qDebug() << "账号或者密码错误" <<endl;
        int res=QMessageBox::information(this,"提示","账号或者密码错误,是否继续登录",QMessageBox::Ok|QMessageBox::No);
        if(res==QMessageBox::Ok){
            ui->passwdLine->setText("");
        }else{
            this->close();
        }

    }
}
void Widget::mousePressEvent(QMouseEvent *event){
    p=event->pos();
}
void Widget::mouseMoveEvent(QMouseEvent *event){
    if(event->buttons()==Qt::LeftButton)
    this->move(event->globalPos()-p);
}

page2.ui:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

widget.ui:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器

运行结果:

QTday05(TCP的服务端客户端通信),tcp/ip,网络,服务器文章来源地址https://www.toymoban.com/news/detail-722496.html

到了这里,关于QTday05(TCP的服务端客户端通信)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++网络通信实例(TCP/IP协议,包括服务端与客户端通信)

    创作不易 觉得有帮助请点赞关注收藏 TCP/IP是当下网络协议栈中的主流协议 TCP属于传输层的协议  可靠传输 包括经典的三次握手等等 IP协议是网络层协议 尽全力传输但不可靠 学过计算机网络的同学们对这个应该比较熟悉 以下是使用C++进行网络通信的实例  服务端 主要使用

    2024年02月14日
    浏览(40)
  • tcp通信,客户端服务端

    //TCP通信的流程 //服务器端(被动接受连接的角色) 1.创建一个用于监听的套接字         -监听:监听有客户端的连接         -套接字:这个套接字其实就是一个文件描述符 2.将这个监听文件描述符和本地的IP和端口绑定(IP和端口就是服务器的地址信息)         -客户端

    2024年02月09日
    浏览(30)
  • TCP实现服务器和客户端通信

    目录 TCP介绍 代码实现 server(服务器端) 代码分析 client(客户端) 代码分析 结果展示 TCP (Transmission Control Protocol) 是一种面向连接的协议,用于在计算机网络中传输数据。TCP 可以确保数据的可靠传输,即使在网络环境不稳定的情况下也能够保证数据的完整性和顺序。以下是

    2024年02月15日
    浏览(44)
  • 简易TCP客户端和服务器端通信

    #includeiostream #include winsock2.h   #include ws2tcpip.h   #includestdlib.h using namespace std; #define  BUF_SIZE  1024 int main() {     cout \\\"客户端\\\" endl;     //设置Winsock版本,     WSADATA   wsaData;     if (WSAStartup(MAKEWORD(2, 2), wsaData) != 0)     {         cout \\\"error\\\" endl;         exit(1);     }     //创建通

    2024年04月29日
    浏览(34)
  • TCP通信实现客户端向服务器发送图片

    TCP通信: 1. TCP 协议通信交互流程: 具体的流程如下: (1)服务器根据地址类型(ipv4、ipv6)、socket 类型、协议创建 socket. (2)服务器为 socket 绑定 ip 地址和端口号。 (3)服务器 socket 监听端口号的请求,随时准备接受来自客户端的连接,此时服务器的 socket 处于关闭状态

    2024年02月13日
    浏览(44)
  • QT实现TCP通信(服务器与客户端搭建)

    创建一个QTcpServer类对象,该类对象就是一个服务器 调用listen函数将该对象设置为被动监听状态,监听时,可以监听指定的ip地址,也可以监听所有主机地址,可以通过指定端口号,也可以让服务器自动选择 当有客户端发来连接请求时,该服务器会自动发射一个newConnection信号

    2024年02月09日
    浏览(41)
  • Java实现TCP客户端和服务器端相互通信

    解决TCP客户端和服务器端通信读不到数据的问题  解决: 服务器端和客户端读完后加上client.shutdownInput(); 服务器端和客户端写完后加上client.shutdownOutput(); 服务器端代码: 客户端代码: 运行服务器端再运行客户端,在客户端中输入要发送的信息,回车 服务器收到信息,over

    2024年02月08日
    浏览(50)
  • 服务端和客户端通信-TCP(含完整源代码)

    目录 简单TCP通信实验 分析 1、套接字类型 2、socket编程步骤 3、socket编程实现具体思路 实验结果截图 程序代码 实验设备:     目标系统:windows 软件工具:vs2022/VC6/dev 实验要求: 完成TCP服务端和客户端的程序编写; 实现简单字符串的收发功能。 需附上代码及运行结果截图

    2024年02月07日
    浏览(59)
  • TCP IP网络编程(四) 基于TCP的服务器端、客户端

    TCP/IP协议栈 ​ TCP/IP协议栈 TCP/IP协议栈共分为4层,可以理解为数据收发分成了4个层次化过程。 ​ TCP协议栈 ​ UDP协议栈 链路层 链路层是物理连接领域标准化的结果,也是最基本的领域,专门定义LAN、WAN、MAN等网络标准。两台主机通过网络进行数据交换,这需要像下图所示

    2024年01月16日
    浏览(41)
  • 【C++】TCP通信服务端与客户端代码实现及详解

    上述代码使用Winsock库实现了简单的TCP服务器,它监听指定端口并与客户端进行通信。下面对代码进行详细分析: #pragma comment(lib, \\\"ws2_32.lib\\\") 是一个特殊的 编译器指令 ,用于告诉编译器在链接阶段将 ws2_32.lib 库文件添加到最终的可执行文件中。无需在编译命令行或IDE中显式指

    2024年02月03日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包