QT程序设计多人聊天室(基于QT、sqlite3、TCP/IP)

这篇具有很好参考价值的文章主要介绍了QT程序设计多人聊天室(基于QT、sqlite3、TCP/IP)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

技术路线

效果展示

程序主体

sqoperator.h

mylogin.h

myenroll.h

chatinterface.h

tips.h

myapp.h

*******************

sqoperator.cpp

mylogin.cpp

myenroll.cpp

chatinterface.cpp

tips.cpp

myapp.cpp

main.cpp

widget.h

widget.cpp

main.cpp


技术路线

QT程序设计、sqlite数据库调用、TCP/IP客户端与服务端的搭建

通过次程序代码,可以学习如何使用纯代码设计界面(非UI),了解如何通过QT调用sqlite数据库,以及如何使用TCP/IP协议简单地搭建客户端与服务端。 此项目中的界面主要做的有两个,一个登录界面,一个聊天消息收发界面,登录界面有登录和注册,通过创建数据库,调用数据库中的数据进行判断,程序实现对数据库中的资源进行增删改查。在界面跳转方面,通过QT独有的信号和槽机制,进行设计,此项目主要在登录界面和消息交互界面设计了界面的跳转。至于客户端和服务端的搭建,是本项目主要需要实现的地方,通过ip地址和端口号,进行,各个客户端之间的通信,数据先通过客户端发往服务端,再由服务端发往客户端,可以实现多个客户端的并发通信,只需要将服务端开启即可。

效果展示

QT程序设计多人聊天室(基于QT、sqlite3、TCP/IP)

QT程序设计多人聊天室(基于QT、sqlite3、TCP/IP)


程序主体

sqoperator.h

这是对数据库的封装,其中有部分封装本项目没用到

#ifndef SQLITEOPERATOR_H
#define SQLITEOPERATOR_H

#include <QWidget>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

typedef struct
{  
    QString usrname;
    QString usrpass;
}info;

//结构体用于存放用户名和密码

class SqOperator : public QWidget
{
    Q_OBJECT
public:
    explicit SqOperator(QWidget *parent = nullptr);

    // 打开数据库
    bool openDb(void);
    // 创建数据表
    void createTable(void);
    // 判断数据表是否存在
    bool isTableExist(QString& tableName);
    // 查询全部数据
    void queryTable(QList<QString> &list);
    // 插入数据
    bool singleInsertData(info &singleData); // 插入单条数据
    void moreInsertData(QList<info> &moreData); // 插入多条数据
    // 修改数据
    void modifyData(QString usrname,QString usrpass);
    // 删除数据
    void deleteData(QString usrname);
    //删除数据表
    void deleteTable(QString& tableName);
    // 关闭数据库
    void closeDb(void);

private:
    QSqlDatabase database;// 用于建立和数据库的连接

};

#endif // SQLITEOPERATOR_H

mylogin.h

#ifndef MYLOGIN_H
#define MYLOGIN_H

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPixmap>

class mylogin : public QDialog
{
    Q_OBJECT

public:
    mylogin(QWidget *parent = nullptr);
    ~mylogin();
    void init_ui();

    QLabel *lb1;
    QLabel *lb2;
    QLabel *lb3;

    QPushButton *bnt_login;
    QPushButton *bnt_register;

    QLineEdit *usr_name_le;
    QLineEdit *usr_pass_le;

    QHBoxLayout *hb1;
    QHBoxLayout *hb2;
    QHBoxLayout *hb3;
    QVBoxLayout *vb1;


signals:
    void sig_login(QString usrname, QString usrpass); //自定义的登录信号,发给myapp
    void sig_enroll();    //自定义的注册信号,发给myapp

public slots:
    void do_login();        //为关联按键和信号发射所设的槽函数
    void do_enroll();

};
#endif // MYLOGIN_H

myenroll.h

#ifndef MYENROLL_H
#define MYENROLL_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPixmap>

class myenroll : public QWidget
{
    Q_OBJECT
public:
    explicit myenroll(QWidget *parent = nullptr);   
    void init_ui();


    QLineEdit * name;
    QLineEdit * pass;
    QLabel * lb1;
    QLabel * lb2;
    QPushButton * bnt1;

    QHBoxLayout * hb1;
    QHBoxLayout * hb2;
    QHBoxLayout * hb3;

    QVBoxLayout * vb1;




signals:
    void sig_enroll_info(QString usrname, QString usrpass); //自定义的注册信号,发送给myapp

public slots:
    void send_msg();    //为注册信号所设置的槽函数
};

#endif // MYENROLL_H

chatinterface.h

#ifndef CHATINTERFACE_H
#define CHATINTERFACE_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPixmap>
#include <QTextEdit>
#include <QTcpSocket>
#include "mylogin.h"

class chatInterface : public QWidget
{
    Q_OBJECT
public:
    explicit chatInterface(QWidget *parent = nullptr);

    void init();

    QLabel * lb1;
    QLineEdit * le1;
    QTextEdit * te1;
    QPushButton * bnt1;
    QHBoxLayout * hb1;
    QVBoxLayout * vb1;


    mylogin * login;
    QTcpSocket * mysock;

signals:

public slots:
    void connect_success_msg();
    void recv_msg_slots();
    void send_msg_slots();


};

#endif // CHATINTERFACE_H

tips.h

#ifndef TIPS_H
#define TIPS_H

#include <QWidget>
#include <QMessageBox>

class tips : public QWidget
{
    Q_OBJECT
public:
    explicit tips(QWidget *parent = nullptr);

    void loginfail();
    void insertok();


signals:

public slots:


};

#endif // TIPS_H

 myapp.h

#ifndef MYAPP_H
#define MYAPP_H

#include <QObject>
#include <QDebug>
#include <QString>
#include "mylogin.h"
#include "myenroll.h"
#include "tips.h"
#include "chatinterface.h"
#include "sqoperator.h"



class myapp : public QObject
{
    Q_OBJECT
public:
    explicit myapp(QObject *parent = nullptr);


    SqOperator *mydb;   //数据库类
    mylogin * login;
    myenroll * enroll;
    tips * tip;//提示信息类
    chatInterface *face;//主界面信息类


signals:


public slots:

    bool judge(QString usrname, QString usrpass);
    void show_enroll_face();
    void insertdb(QString usrname,QString usrpass);

};

#endif // MYAPP_H

*******************

sqoperator.cpp

#include "sqoperator.h"

SqOperator::SqOperator(QWidget *parent) : QWidget(parent)
{
    if (QSqlDatabase::contains("qt_sql_default_connection"))
        {
            database = QSqlDatabase::database("qt_sql_default_connection");
        }
        else
        {
            // 建立和SQlite数据库的连接
            database = QSqlDatabase::addDatabase("QSQLITE");
            // 设置数据库文件的名字
            database.setDatabaseName("chatapp.db");
        }
}

// 打开数据库
bool SqOperator::openDb()
{
    if (!database.open())
    {
        qDebug() << "Error: Failed to connect database." << database.lastError();
        return false;
    }
    else
    {
        qDebug() <<"open database success";
    }

    return true;
}

// 创建数据表
void SqOperator::createTable()
{
    // 用于执行sql语句的对象
    QSqlQuery sqlQuery;
    // 构建创建数据库的sql语句字符串
    QString createSql = QString("CREATE TABLE if not exists idinfo(usrname TEXT PRIMARY KEY ,usrpass TEXT NOT NULL)");
    sqlQuery.prepare(createSql);

    // 执行sql语句
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to create table. " << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "Table created!";
    }
}

// 判断数据库中某个数据表是否存在
bool SqOperator::isTableExist(QString& tableName)
{
    QSqlDatabase database = QSqlDatabase::database();
    if(database.tables().contains(tableName))
    {
        return true;
    }

    return false;
}

// 查询全部数据,这里需要改造一下,我们传入一个空容器,然后,把数据弄出去
void SqOperator::queryTable(QList<QString> &list)
{
    QSqlQuery sqlQuery;
    sqlQuery.exec("SELECT * FROM idinfo");
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to query table. " << sqlQuery.lastError();
    }
    else
    {
        while(sqlQuery.next())
        {
            QString usrname = sqlQuery.value(0).toString();
            list.append(usrname);
            QString usrpass = sqlQuery.value(1).toString();
            list.append(usrpass);

            //qDebug()<<QString("id:%1    name:%2").arg(id).arg(name);
        }
    }
}

// 插入单条数据
bool SqOperator::singleInsertData(info &singledb)
{
    QSqlQuery sqlQuery;
    sqlQuery.prepare("INSERT INTO idinfo VALUES(:usrname,:usrpass)");
    sqlQuery.bindValue(":usrname", singledb.usrname);
    sqlQuery.bindValue(":usrpass", singledb.usrpass);

    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
        return false;
    }
    else
    {
        qDebug() <<"insert success.";
        // do something
        return true;
    }
}

// 插入多条数据
void SqOperator::moreInsertData(QList<info>& moredb)
{
    // 进行多个数据的插入时,可以利用绑定进行批处理
    QSqlQuery sqlQuery;
    sqlQuery.prepare("INSERT INTO idinfo VALUES(?,?,?)");
    QVariantList nameList,passList;
    for(int i=0; i< moredb.size(); i++)
    {
        nameList <<  moredb.at(i).usrname;
        passList << moredb.at(i).usrpass;

    }
    sqlQuery.addBindValue(nameList);
    sqlQuery.addBindValue(passList);


    if (!sqlQuery.execBatch()) // 进行批处理,如果出错就输出错误
    {
        qDebug() << sqlQuery.lastError();
    }
}

// 修改数据
void SqOperator::modifyData(QString usrname,QString usrpass)
{
    QSqlQuery sqlQuery;
    sqlQuery.prepare("UPDATE student SET usrname=?,usrpass=?");
    sqlQuery.addBindValue(usrname);
    sqlQuery.addBindValue(usrpass);
    if(!sqlQuery.exec())
    {
        qDebug() << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "updated data success!";
    }
}

// 删除数据
void SqOperator::deleteData(QString usrname)
{
    QSqlQuery sqlQuery;

    sqlQuery.exec(QString("DELETE FROM student WHERE id = %1").arg(usrname));
    if(!sqlQuery.exec())
    {
        qDebug()<<sqlQuery.lastError();
    }
    else
    {
        qDebug()<<"deleted data success!";
    }
}

//删除数据表
void SqOperator::deleteTable(QString& tableName)
{
    QSqlQuery sqlQuery;

    sqlQuery.exec(QString("DROP TABLE %1").arg(tableName));
    if(sqlQuery.exec())
    {
        qDebug() << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "deleted table success";
    }
}

void SqOperator::closeDb(void)
{
    database.close();
}

mylogin.cpp

#include "mylogin.h"

mylogin::mylogin(QWidget *parent)
    : QDialog(parent)
{
    this->init_ui();

    connect(this->bnt_login, &QPushButton::clicked, this, &mylogin::do_login);
    connect(this->bnt_register, &QPushButton::clicked , this ,&mylogin::do_enroll);

}

mylogin::~mylogin()
{

}

void mylogin::init_ui()
{
    this->setFixedSize(QSize(600,350));
    this->setWindowTitle(tr("大飞秋"));
    this->setWindowIcon(QIcon(":/src/1.png"));

    this->lb1 = new QLabel();
    this->lb2 = new QLabel();
    this->lb3 = new QLabel();

    this->lb1->setFixedSize(QSize(560,200));
    QPixmap pic;
    pic.load(":/src/2.png");
    //this->lb1->setPixmap(pic.scaled(this->lb1->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
    this->lb1->setPixmap(QPixmap(":/src/2.png"));

    this->lb2->setText(tr("用户名:"));
    this->lb3->setText(tr("密  码:"));

    this->usr_name_le = new QLineEdit();    //这两个参数后面传入信号中去,然后emit发射出去
    this->usr_pass_le = new QLineEdit();

    this->usr_pass_le->setEchoMode(QLineEdit::Password);

    this->bnt_login = new QPushButton(tr("登  陆"));
    this->bnt_register = new QPushButton(tr("注  册"));

    this->hb1 = new QHBoxLayout();
    this->hb2 = new QHBoxLayout();
    this->hb3 = new QHBoxLayout();

    this->hb1->addWidget(this->lb2);
    this->hb1->addWidget(this->usr_name_le);

    this->hb2->addWidget(this->lb3);
    this->hb2->addWidget(this->usr_pass_le);

    this->hb3->addWidget(this->bnt_login);
    this->hb3->addWidget(this->bnt_register);

    this->vb1 = new QVBoxLayout();
    this->vb1->addWidget(this->lb1);
    this->vb1->addLayout(this->hb1);
    this->vb1->addLayout(this->hb2);
    this->vb1->addLayout(this->hb3);

    this->setLayout(this->vb1);

}

void mylogin::do_login()
{
    emit sig_login(usr_name_le->text(), usr_pass_le->text());
    //需要把这里输入的账号密码信息发送到myapp那去,用到的函数是emit
    //需要自定义一个信号,sig_login
    //这个槽函数能够发出信号
}

void mylogin::do_enroll()
{
    emit sig_enroll();
}

myenroll.cpp

#include "myenroll.h"

myenroll::myenroll(QWidget *parent) : QWidget(parent)
{
    init_ui();
    connect(this->bnt1,&QPushButton::clicked,this,&myenroll::send_msg);
}


void myenroll::init_ui()
{
    this->setFixedSize(QSize(600,350));
    this->setWindowTitle(tr("信息注册"));
    this->setWindowIcon(QIcon(":/src/1.png"));


    name = new QLineEdit;           //用于写入名字
    pass = new QLineEdit;           //用于写入密码
    lb1 = new QLabel;
    lb2 = new QLabel;

    bnt1 = new QPushButton;

    hb1 = new QHBoxLayout;
    hb2 = new QHBoxLayout;
    hb3 = new QHBoxLayout;

    vb1 = new QVBoxLayout;

    this->lb1->setText(tr("请输入账号:"));
    this->lb2->setText(tr("请输入密码:"));
    this->bnt1->setText(tr("确认"));

    this->hb1->addWidget(lb1);
    this->hb1->addWidget(name);
    this->hb2->addWidget(lb2);
    this->hb2->addWidget(pass);
    this->hb3->addWidget(bnt1);

    this->vb1->addLayout(hb1);
    this->vb1->addLayout(hb2);
    this->vb1->addLayout(hb3);

    this->setLayout(vb1);


}

void myenroll::send_msg()
{
    emit sig_enroll_info(name->text(),pass->text());
}


 chatinterface.cpp

#include "chatinterface.h"

chatInterface::chatInterface(QWidget *parent) : QWidget(parent)
{
    this->init();

}


void chatInterface::init()
{
    this->setFixedSize(QSize(600,900));
    this->setWindowTitle(tr("大飞秋"));
    this->setWindowIcon(QIcon(":/src/1.png"));

    lb1 = new QLabel;
    le1 = new QLineEdit;
    te1 = new QTextEdit;
    bnt1 = new QPushButton;
    hb1 = new QHBoxLayout;
    vb1 = new QVBoxLayout;

    this->lb1->setFixedSize(QSize(565,80));
    QPixmap pic;
    pic.load(":/src/3.jpg");
    this->lb1->setPixmap(pic.scaled(this->lb1->size()));

    this->te1->setFixedSize(QSize(560,700));
    this->te1->setStyleSheet(QString("background-color:") + "white");


    this->le1->setFixedSize(QSize(450,50));
    this->bnt1->setText(tr("发送"));
    this->bnt1->setFixedSize(QSize(100,50));

    this->hb1->addWidget(le1);
    this->hb1->addWidget(bnt1);
    this->vb1->addWidget(lb1);
    this->vb1->addWidget(te1);
    this->vb1->addLayout(hb1);

    this->setLayout(vb1);

    this->mysock = new QTcpSocket();
    this->mysock->connectToHost("192.168.4.32",8888);    //需查看自己的本机ip写入
    connect(this->mysock, &QTcpSocket::connected, this, &chatInterface::connect_success_msg);
    connect(this->mysock, &QTcpSocket::readyRead, this, &chatInterface::recv_msg_slots);
    connect(this->bnt1, &QPushButton::clicked, this, &chatInterface::send_msg_slots);




}



void chatInterface::connect_success_msg()
{
    qDebug() << "链接服务器成功";
}

void chatInterface::recv_msg_slots()
{
    QByteArray con = this->mysock->readAll();
    QString *str = new QString(con);
    this->te1->append(*str);
}


void chatInterface::send_msg_slots()
{

    this->te1->append(this->le1->text());
    this->mysock->write( (this->le1->text()).toUtf8());
}




tips.cpp

#include "tips.h"

tips::tips(QWidget *parent) : QWidget(parent)
{

}

void tips::loginfail()
{
    QMessageBox msg;
    msg.warning(this,tr("登录提示"),tr("账号或密码错误,请重新登录!"));
}
void tips::insertok()
{
    QMessageBox msg;
    msg.warning(this,tr("信息注册"),tr("用户注册成功!"));
}

 myapp.cpp

#include "myapp.h"

myapp::myapp(QObject *parent) : QObject(parent)
{

    //创建并打开SQLite数据库
    this->mydb = new SqOperator;
    mydb->openDb();
    //创建数据表
    mydb->createTable();

    //这里分别新建的是登录和注册两个对象
    this->login = new mylogin;
    this->login->show();
    this->enroll = new myenroll;

    this->face = new chatInterface;
    this->tip = new tips;

    connect(login,&mylogin::sig_login,this,&myapp::judge);
    connect(login,&mylogin::sig_enroll,this,&myapp::show_enroll_face);
    connect(enroll,&myenroll::sig_enroll_info,this,&myapp::insertdb);

}


bool myapp::judge(QString usrname, QString usrpass)
{
    qDebug()<<usrname<<usrpass;
    //查询全部数据,并且放入list中
    QList<QString> list;
    mydb->queryTable(list);

    int i = 0;
    //当存在两个账号的时候,这里循环里面的if必定会进去,错误和正确都会提示,应该在正确之后直接结束判断,而错误提示则应该放在循环结束
    for(i = 0 ; i < list.size() ; i=i+2)
    {

        if(usrname == list[i] || usrpass == list[i+1])
        {

            this->face->show();
            return true;
        }
    }

    this->tip->loginfail();
    return false;

}
void myapp::show_enroll_face()
{
    this->enroll->show();
}

void myapp::insertdb(QString usrname,QString usrpass)
{
    qDebug()<<usrname<<usrpass;
    info info1;
    info1.usrname = usrname;
    info1.usrpass = usrpass;
    if(mydb->singleInsertData(info1))
    {
        this->tip->insertok();
    }
}

main.cpp

#include "myapp.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    myapp w;
    return a.exec();
}

 程序至此,只是写了客户端的部分,下面是服务端文章来源地址https://www.toymoban.com/news/detail-494374.html

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTextEdit>
#include <QHBoxLayout>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
public:
    QTcpServer *myser;
    QList <QTcpSocket *> myclis;//是一个QTcpSocket *类型的容器,可实现多个客户端socket的存放

    QTextEdit *myte;
    QHBoxLayout *hb1;

private slots:
    void accept_client();
    void do_work();
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->myte = new QTextEdit();
    this->hb1 = new QHBoxLayout();

    this->hb1->addWidget(this->myte);
    this->setLayout(this->hb1);

    this->myser = new QTcpServer();
    this->myser->listen(QHostAddress::AnyIPv4,8888);    //IP协议和端口号
    this->myclis.clear();

    connect(this->myser,&QTcpServer::newConnection,this,&Widget::accept_client);
}

Widget::~Widget()
{

}



void Widget::accept_client()
{
    QTcpSocket * mysck = this->myser->nextPendingConnection();
    this->myclis.append(mysck); //接收客户端的连接请求
    connect(mysck,&QTcpSocket::readyRead,this,&Widget::do_work);//接收到信号后准备读,所以,我们需要一个读的槽函数去接收这个准备好的信号

}


void Widget::do_work()//实现
{
    QTcpSocket *sck = (QTcpSocket *)sender();
    QByteArray con = sck->readAll();
    //遍历
    for(int i = 0;i < this->myclis.size();i++)
    {
        if(this->myclis[i] == sck)
        {
            continue;
        }
        this->myclis[i]->write(con);
    }

}

 main.cpp

#include "widget.h"
#include <QApplication>

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

    return a.exec();
}

到了这里,关于QT程序设计多人聊天室(基于QT、sqlite3、TCP/IP)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Java socket编程】多人聊天室

    课程设计大作业 功能: 1.具有 点对点通信 功能,任意客户端之间能够发送消息。 2.具有 群组通信 功能: 客户端可以 自主建立群组 ,添加或删除组成员; 客户端能够向组内成员同时发送消息,其他组成员不能收到。 3.具有 广播 功能 客户端能够向所有其他成员 广播消息

    2024年02月04日
    浏览(40)
  • 基于Python web的多人聊天室

              本文介绍了基于即时通讯的Python实现web版多人聊天室的设计和实现。这个系统利用了多种先进的技术,如Django、Channels、WebSocket,来实现即时通信,并利用MySQL和Redis作为数据库,同时还采用了多种前端技术,如bootstrap、CSS、html和js,来提供出色的用户体验。该系

    2024年02月16日
    浏览(40)
  • vue3-多人聊天室角色识别(全栈)

    主要技术栈是vue3,springboot,websocket,element-plus 主要目的是复习和梳理 发送信息,包装信息,转json,用socket发送到后端,使输入栏清空 后端解析json,因为是socket接口,所以不能用@requestbody解析json,用以下方式解析json 设置发送时间为当前时间,然后执行mapper数据库插入 广

    2024年02月11日
    浏览(40)
  • Python多人聊天室-基于socket UDP协议

    使用Python编写的基于socket UDP通信的多功能即时聊天室,包含Tkinter编写的图形化聊天界面,功能包括有账号注册和登录,登录成功后可以查看在线用户,并和聊天室内的其他在线用户聊天,包含私聊和群发,能发送文字、表情包,以及文件等。 登录和注册 显示在线用户 群聊

    2024年02月11日
    浏览(58)
  • 【Linux网络编程】基于UDP实现多人聊天室

    UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。 数据报格式套接字 SOCK_DGRAM 采用UDP只管发送数据而不去验证发送数据的正确性,不论传输是否被接收,数据流是否有丢失,都不再重新发

    2024年02月08日
    浏览(57)
  • C语言实现--基于UDP的多人在线聊天室

    目录 实现功能 实现思想 实现代码(部分及详解) 服务端部分代码 客户端部分代码 实现效果 项目中出现的问题和解决方法 项目整体代码展示 代码优化思路 服务端代码 客户端代码 服务端可以同时连接多个客户端; 新的客户端连接服务端时,可以在服务端显示自己的名字并

    2024年02月04日
    浏览(64)
  • Linux-Socket实现模拟群聊(多人聊天室)

    简单版本 服务端源码 客户端源码 服务器可以在特定的端口监听客户端的连接请求,若连接成功,服务器采用广播的形式向当前所有连接客户端发送该客户端登录成功消息多个客户端可以同时登录,在源码文件中可以配置最多群聊同时在线人数。服务端接收到客户端发送的群

    2024年02月10日
    浏览(93)
  • 多人聊天室(带私聊功能)Linux网络编程基础

    在和同学一起努力下终于完成了期末作业哈哈哈哈 文章目录 目录 前言 一、需求分析 二、功能设计 1.服务器端: 2.客户端: 三、流程图: 编程流程图: 服务器流程图: 客户端流程图: 四、运行效果: 项目源码: 服务器源码 客户端源码: 总结: Linux网络编程是我们这学

    2024年02月09日
    浏览(59)
  • WebSocket+Vue实现简易多人聊天室 以及 对异步调用的理解

    代码仓库:github   HTTP是不支持长连接的,WebSocket是一种通信协议,提供了在单一、长连接上进行全双工通信的方式。它被设计用于在Web浏览器和Web服务器之间实现,但也可以用于任何需要实时通信的应用程序。使用ws作为协议标识符,如果需要加密则使用wss作为协议标识符

    2024年01月17日
    浏览(61)
  • 【Unity工具,简单应用】Photon + PUN 2,做一个简单多人在线聊天室

    【Unity工具,简单学习】PUN 2,多人在线游戏开发,初步使用 需要有一定 UNITY 使用经验的开发者可以顺利阅读。 简单搭建一下大厅UI。 给 Laucher 节点一个 Launcher 脚本 Launcher 脚本如下,具体功能看注释 需要注意的是 PhotonNetwork.JoinOrCreateRoom(RoomName, new RoomOptions() { MaxPlayers = ma

    2024年02月08日
    浏览(56)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包