作业内容
利用QT搭建基于TCP的模拟QQ聊天界面,实现多个客户端同时聊天
代码部分
服务器:
ser.h:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146在这里插入代码片 ```#ifndef CHATCLI_H #define CHATCLI_H #include <QWidget> #include <QTcpSocket> QT_BEGIN_NAMESPACE namespace Ui { class chatcli; } QT_END_NAMESPACE class chatcli : public QWidget { Q_OBJECT public: explicit chatcli(QWidget *parent = nullptr); ~chatcli(); private slots: void on_connectbtn_clicked(); void on_connectbtn_solt(); //connect信号对应槽函数的声明 void on_disconnectbtn_solt(); //disconnect信号对应槽函数的声明 void on_readyRead_solt(); void on_sendbtn_clicked(); private: Ui::chatcli *ui; //定义客户端套接字指针 QTcpSocket *socket; //定义用户名 QString username; //定义bool类型数据,表示连接状态 bool isOK; }; #endif // CHATCLI_H ser.cpp: ```cpp #include "chatcli.h" #include "ui_chatcli.h" #include <QHostAddress> chatcli::chatcli(QWidget *parent) : QWidget(parent) , ui(new Ui::chatcli) { ui->setupUi(this); ui->sendbtn->setEnabled(false);//发送信息按钮设置为不可用 //实例化socket对象 socket = new QTcpSocket(this); //给连接状态初始值 isOK = false; //将connected信号连接到自定义的槽函数中处理相关函数 connect(socket,&QTcpSocket::connected,this,&chatcli::on_connectbtn_solt); //将disconnected信号连接到自定义的槽函数中处理相关函数 connect(socket,&QTcpSocket::disconnected,this,&chatcli::on_disconnectbtn_solt); //当客户端接收到服务器发的消息会触发一个readyRead信号,在该信号对的槽函数中书写逻辑 connect(socket,&QTcpSocket::readyRead,this,&chatcli::on_readyRead_solt); } chatcli::~chatcli() { delete ui; } //连接服务器按钮对应的槽函数 void chatcli::on_connectbtn_clicked() { QString ip = ui->iptext->text(); quint16 port = quint16(ui->porttext->text().toUInt()); //判断连接状态 if(isOK == false) { //连接服务器 /*功能:客户端连接服务器函数 * 参数:address:主机地址,port:端口号 */ //获取ip和端口号 socket->connectToHost(QHostAddress(ip),port); //一旦连接成功,就会触发一个connected的信号,在该信号对应的槽函数中处理逻辑 //将按钮文本改为断开连接 ui->connectbtn->setText("断开连接"); isOK = true; } else{ //断开服务器 /*功能:断开该客户端的连接 * 参数:返回值:无 */ username = ui->nametext->text(); QString mes = username + "离开群聊"; socket->write(mes.toLocal8Bit());//告诉服务器我走了 socket->disconnectFromHost(); //将按钮文本改为连接服务器 ui->connectbtn->setText("连接服务器"); isOK = false; } } //connect信号对应槽函数的定义 void chatcli::on_connectbtn_solt() { username = ui->nametext->text(); QString mes = username + "加入群聊"; ui->nametext->setEnabled(false);//输入用户名栏设置为不可用 ui->iptext->setEnabled(false);//输入ip栏设置为不可用 ui->porttext->setEnabled(false);//输入端口号栏设置为不可用 ui->sendbtn->setEnabled(true);//发送信息按钮变为可用 socket->write(mes.toLocal8Bit());//告诉服务器我来了 } //disconnect信号对应槽函数的定义 void chatcli::on_disconnectbtn_solt() { ui->nametext->setEnabled(true);//输入用户名栏设置为可用 ui->iptext->setEnabled(true);//输入ip栏设置为可用 ui->porttext->setEnabled(true);//输入端口号栏设置为可用 ui->sendbtn->setEnabled(false);//发送信息按钮变为可用 } //readyRead信号对应槽函数的定义 void chatcli::on_readyRead_solt() { //获取套接字中的数据 QString mes = QString::fromLocal8Bit(socket->readAll()); //将数据显示在list Widge中 ui->listWidget->addItem(mes); } //发送按钮对应槽函数 void chatcli::on_sendbtn_clicked() { username = ui->nametext->text(); QString mes = username + ":" + ui->sendtext->text(); //将数据发送给服务器 socket->write(mes.toLocal8Bit()); //将发送数据框中数据清空 ui->sendtext->clear(); }
客户端:
cli.h:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#ifndef CHATSERVER_H #define CHATSERVER_H #include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> QT_BEGIN_NAMESPACE namespace Ui { class chatserver; } QT_END_NAMESPACE class chatserver : public QWidget { Q_OBJECT public: explicit chatserver(QWidget *parent = nullptr); ~chatserver(); private slots: void on_startBtn_clicked(); //信号对应槽函数的声明 void on_newConnection_slot(); //readyRead对应槽函数 void on_readyRead_slot(); //发送信息槽函数 void send(QString mes); private: Ui::chatserver *ui; //定义一个服务器指针 QTcpServer *server; //定义客户端指针,盛放连接的客户端(同hi多个客户端,用链表存) QList<QTcpSocket *> socketList; }; #endif // CHATSERVER_H
cli.c:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77#include "chatserver.h" #include "ui_chatserver.h" chatserver::chatserver(QWidget *parent) : QWidget(parent) , ui(new Ui::chatserver) { ui->setupUi(this); //实例化服务器 server = new QTcpServer(this); } chatserver::~chatserver() { delete ui; } //启动按钮对应的槽函数 void chatserver::on_startBtn_clicked() { quint16 port = quint16(ui->portlab->text().toInt()); //将服务器设置为监听状态 server->listen(QHostAddress::Any,port); //将相应的控件设置为不可用状态 ui->startBtn->setEnabled(false); //当有新的客户端连接,会发出一个newConnection信号 connect(server,&QTcpServer::newConnection,this,&chatserver::on_newConnection_slot); } //connection对应的槽函数 void chatserver::on_newConnection_slot() { /*功能:获取最新连接客户端的套接字 * 参数:无 * 返回值:新客户端的套接字 */ QTcpSocket * socket = server->nextPendingConnection(); //将新套接字放入套接字链表中 socketList.append(socket); //当服务器接收到客户端传过来的消息时就会触发一个readRead信号,在该信号对应的槽函数中处理相关逻辑 connect(socket,&QTcpSocket::readyRead,this,&chatserver::on_readyRead_slot); } //readyRead对应的槽函数 void chatserver::on_readyRead_slot() { //遍历客户端的链表,判断时哪个客户端发送信息 for(quint16 i=0;i<socketList.count();i++) { /*功能:获取客户端中待读取数据的个数 * 功能:无 * 返回值:待读取数据的个数 */ if(socketList.at(i)->bytesAvailable()) { /*功能:获取客户端传过来的待读数据 * 参数:无 * 返回值:QByteArray类型的数据 */ QString mes = QString::fromLocal8Bit(socketList.at(i)->readAll()); //将消息展示到list widget上 ui->listWidget->addItem(mes); //同时还要把该消息进行广播出去 send(mes); } } } //自定义发送消息函数 void chatserver::send(QString mes) { for(int i=0;i<socketList.count();i++) { socketList.at(i)->write(mes.toLocal8Bit()); } }
运行结果
最后
以上就是含糊信封最近收集整理的关于9.5日作业作业内容的全部内容,更多相关9内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复