文章目录
- 成品效果图:
- 代码:
- 工具头文件tool.h
- UI文件代码 ui_widget.h:
- 窗口头文件 widget.h:
- 窗口源文件widget.cpp:
- 相关代码说明:
- Qt获取本机ip:
- Qt 打开,监视服务端端口:
- Qt 客户端连接服务端:
- Qt 服务端被连接后接收显示并接收消息:
- Qt 发送消息:
- 最后:
- 成品:
背景:
最近计网要结课了,匆忙之间有个计网实验还没做。
上网这里查查那里查查,随便搞搞
然后在 这篇文章里找到了能够实现的代码
自己想着把它图形化一下,最后在超级棒棒糖的帮助下实现了。
成品效果图:
代码:
工具头文件tool.h
该头文件用于添加一些要用到的库,直接引用这个库,比较方便美观
#ifndef TOOL_H
#define TOOL_H
#include<winsock2.h>
#include<QDateTime>
#include <ws2tcpip.h>
#include <stdio.h>
#include <QDebug>
#include <QNetworkInterface>
#include <QNetworkInterface>
#include <QDebug>
#include <QtNetwork>
#endif // TOOL_H
UI文件代码 ui_widget.h:
/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.12.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_WIDGET_H
#define UI_WIDGET_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QTextBrowser>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Widget
{
public:
QLabel *label;
QTextBrowser *SeverState;
QFrame *line;
QToolButton *send;
QFrame *line_2;
QTextBrowser *talk;
QWidget *horizontalLayoutWidget;
QHBoxLayout *horizontalLayout;
QLabel *label_2;
QLineEdit *posline;
QToolButton *Open;
QGroupBox *groupBox;
QLabel *label_3;
QLineEdit *TheIp;
QLabel *label_4;
QLineEdit *TheHost;
QToolButton *connectIp;
QTextBrowser *Showip;
QLabel *label_5;
QTextBrowser *connectState;
QTextEdit *TextCin;
void setupUi(QWidget *Widget)
{
if (Widget->objectName().isEmpty())
Widget->setObjectName(QString::fromUtf8("Widget"));
Widget->resize(1106, 823);
label = new QLabel(Widget);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(20, 180, 131, 41));
label->setStyleSheet(QString::fromUtf8("font:20px"));
SeverState = new QTextBrowser(Widget);
SeverState->setObjectName(QString::fromUtf8("SeverState"));
SeverState->setGeometry(QRect(10, 240, 271, 131));
line = new QFrame(Widget);
line->setObjectName(QString::fromUtf8("line"));
line->setGeometry(QRect(350, 610, 761, 21));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
send = new QToolButton(Widget);
send->setObjectName(QString::fromUtf8("send"));
send->setGeometry(QRect(940, 720, 151, 71));
send->setStyleSheet(QString::fromUtf8("font:30px"));
line_2 = new QFrame(Widget);
line_2->setObjectName(QString::fromUtf8("line_2"));
line_2->setGeometry(QRect(340, 0, 31, 821));
line_2->setFrameShape(QFrame::VLine);
line_2->setFrameShadow(QFrame::Sunken);
talk = new QTextBrowser(Widget);
talk->setObjectName(QString::fromUtf8("talk"));
talk->setGeometry(QRect(370, 20, 721, 571));
horizontalLayoutWidget = new QWidget(Widget);
horizontalLayoutWidget->setObjectName(QString::fromUtf8("horizontalLayoutWidget"));
horizontalLayoutWidget->setGeometry(QRect(0, 80, 351, 71));
horizontalLayout = new QHBoxLayout(horizontalLayoutWidget);
horizontalLayout->setSpacing(6);
horizontalLayout->setContentsMargins(11, 11, 11, 11);
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
horizontalLayout->setContentsMargins(0, 0, 0, 0);
label_2 = new QLabel(horizontalLayoutWidget);
label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setStyleSheet(QString::fromUtf8("font:25px;"));
horizontalLayout->addWidget(label_2);
posline = new QLineEdit(horizontalLayoutWidget);
posline->setObjectName(QString::fromUtf8("posline"));
horizontalLayout->addWidget(posline);
Open = new QToolButton(horizontalLayoutWidget);
Open->setObjectName(QString::fromUtf8("Open"));
Open->setStyleSheet(QString::fromUtf8("font:30px"));
horizontalLayout->addWidget(Open);
groupBox = new QGroupBox(Widget);
groupBox->setObjectName(QString::fromUtf8("groupBox"));
groupBox->setGeometry(QRect(10, 390, 301, 261));
groupBox->setStyleSheet(QString::fromUtf8("font:20px"));
label_3 = new QLabel(groupBox);
label_3->setObjectName(QString::fromUtf8("label_3"));
label_3->setGeometry(QRect(10, 30, 221, 31));
TheIp = new QLineEdit(groupBox);
TheIp->setObjectName(QString::fromUtf8("TheIp"));
TheIp->setGeometry(QRect(10, 60, 281, 31));
label_4 = new QLabel(groupBox);
label_4->setObjectName(QString::fromUtf8("label_4"));
label_4->setGeometry(QRect(10, 110, 151, 41));
TheHost = new QLineEdit(groupBox);
TheHost->setObjectName(QString::fromUtf8("TheHost"));
TheHost->setGeometry(QRect(10, 160, 281, 31));
connectIp = new QToolButton(groupBox);
connectIp->setObjectName(QString::fromUtf8("connectIp"));
connectIp->setGeometry(QRect(20, 210, 161, 41));
Showip = new QTextBrowser(Widget);
Showip->setObjectName(QString::fromUtf8("Showip"));
Showip->setGeometry(QRect(115, 10, 231, 41));
label_5 = new QLabel(Widget);
label_5->setObjectName(QString::fromUtf8("label_5"));
label_5->setGeometry(QRect(10, 10, 101, 41));
label_5->setStyleSheet(QString::fromUtf8("font:25px"));
connectState = new QTextBrowser(Widget);
connectState->setObjectName(QString::fromUtf8("connectState"));
connectState->setGeometry(QRect(30, 660, 256, 151));
TextCin = new QTextEdit(Widget);
TextCin->setObjectName(QString::fromUtf8("TextCin"));
TextCin->setGeometry(QRect(360, 620, 561, 191));
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
} // setupUi
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QApplication::translate("Widget", "\345\260\217chat", nullptr));
label->setText(QApplication::translate("Widget", "\346\234\215\345\212\241\347\253\257\347\212\266\346\200\201\357\274\232", nullptr));
send->setText(QApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));
label_2->setText(QApplication::translate("Widget", "\346\234\215\345\212\241\345\231\250\345\274\200\346\224\276\347\253\257\345\217\243", nullptr));
Open->setText(QApplication::translate("Widget", "\346\211\223\345\274\200", nullptr));
groupBox->setTitle(QApplication::translate("Widget", "\350\277\236\346\216\245\345\214\272", nullptr));
label_3->setText(QApplication::translate("Widget", "\345\257\271\346\226\271\346\234\215\345\212\241\345\231\250ip\357\274\232", nullptr));
label_4->setText(QApplication::translate("Widget", "\345\257\271\346\226\271\346\234\215\345\212\241\347\253\257\345\217\243\357\274\232", nullptr));
connectIp->setText(QApplication::translate("Widget", "\350\277\236\346\216\245", nullptr));
label_5->setText(QApplication::translate("Widget", "\346\234\254\346\234\272ip:", nullptr));
} // retranslateUi
};
namespace Ui {
class Widget: public Ui_Widget {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_WIDGET_H
窗口头文件 widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "tool.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
QTcpServer server; //TCP控制本地服务器
quint16 host; //开放端口
QTcpSocket *socket = new QTcpSocket(this); //连接其他的Socket
QTcpSocket *so = new QTcpSocket(this); //被连接的Socket
QString AimIp;
quint16 AimPort;
private slots:
void openHost(); //开放某个端口
void toConnect(); //连接端口
void toSend(); //发送信息
};
#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);
QList<QHostAddress> list = QNetworkInterface::allAddresses();
for(int nIter=0; nIter<list.count(); nIter++)
{
if(!list[nIter].isLoopback())
{
if(list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
{
qDebug() << list[nIter].toString();
ui->Showip->append(list[nIter].toString());
}
}
}
connect(ui->Open, &QToolButton::clicked,this, &Widget::openHost);//打开端口
connect(ui->connectIp, &QToolButton::clicked,this,&Widget::toConnect);//连接
connect(ui->send, &QToolButton::clicked, this,&Widget::toSend);
//被连接
connect(&server, &QTcpServer::newConnection, this, [=]() {
so = server.nextPendingConnection();
QString ip = so->peerAddress().toString();
quint16 port = so->peerPort();
qDebug() << "New connection from " << ip << ":" << port;
QString m = "<font color='blue'>有新的连接来自"+ip+":"+QString::number(port)+"</font>";
ui->SeverState->append(m);
//被连接后接收信息:
connect(so, &QTcpSocket::readyRead, this, [=]() {
QDateTime currentDateTime = QDateTime::currentDateTime();
QString ip = so->peerAddress().toString();
QByteArray data = so->readAll();
qDebug() << "Received data:" << data;
QString mag1 = QString::fromUtf8(data);
qDebug()<<currentDateTime;
QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+mag1+"</font>";
ui->talk->append(mag);
});
});
//连接成功:
connect(socket, &QTcpSocket::connected, this, [=]() {
qDebug() << "Connected to server.";
// 发送信息给服务端
QByteArray message = "连接你了";
socket->write(message);
});
// 接收服务端发送的信息
connect(socket, &QTcpSocket::readyRead, this, [=]() {
QDateTime currentDateTime = QDateTime::currentDateTime();
QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
QString ip = socket->peerAddress().toString();
QByteArray data = socket->readAll();
QString message = QString::fromUtf8(data);
qDebug() << "Received message from server:" << message;
QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+message+"</font>";
ui->talk->append(mag);
});
}
void Widget::openHost(){
int temp = this->ui->posline->text().toInt();
this->host = static_cast<quint16>(temp);
qDebug()<<"端口:"<<this->host<<endl;
server.close();
if(!this->server.listen(QHostAddress::Any, this->host)){
qDebug()<<"端口开放失败"<<endl;
this->ui->SeverState->append("<font color='red'>端口开放失败</font>");
}
else{
this->ui->SeverState->append(this->ui->posline->text()+"端口已开放");
}
}
void Widget::toConnect(){
AimIp = ui->TheIp->text();
int h = ui->TheHost->text().toInt();
AimPort = static_cast<quint16>(h);
socket->connectToHost(AimIp,AimPort);
if (socket->waitForConnected()) {
// 连接成功
qDebug() << "Connected to server!";
QString mag = "连接"+this->AimIp+"的端口"+ui->TheHost->text()+"成功";
ui->connectState->append(mag);
} else {
// 连接失败
QString mag = "连接"+this->AimIp+"的端口"+ui->TheHost->text()+"失败";
qDebug() << "Failed to connect to server: " << socket->errorString();
mag = "<font color='red'>"+mag+"</font>";
ui->connectState->append(mag);
}
}
void Widget::toSend(){
QString mag = this->ui->TextCin->toPlainText();
so->write(mag.toUtf8());
so->flush();
so->waitForBytesWritten();
socket->write(mag.toUtf8());
socket->flush();
socket->waitForBytesWritten();
QDateTime currentDateTime = QDateTime::currentDateTime();
QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
QString smag = strDateTime+"向"+this->AimIp+"发送消息:"+mag;
ui->talk->append(smag);
ui->TextCin->clear();
}
Widget::~Widget()
{
delete ui;
}
相关代码说明:
Qt获取本机ip:
QList<QHostAddress> list = QNetworkInterface::allAddresses();
for(int nIter=0; nIter<list.count(); nIter++)
{
if(!list[nIter].isLoopback())
{
if(list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
{
qDebug() << list[nIter].toString();//输出端口信息
}
}
}
Qt 打开,监视服务端端口:
QTcpServer server;
quint16 host = 8080;
server.listen(QHostAddress::Any, host);
这里的listen()函数则是打开端口并监视,不过要注意,一个server只能打开监视一个端口。
Qt 客户端连接服务端:
这里的客户端其实也就是你自己的主机,你自己的主机也可以充当服务端捏。
QString AimIp = "127.0.0.1"
quint16 AimPort = 8080;
QTcpSocket *socket = new QTcpSocket();
socket->connectToHost(AimIp,AimPort);//连接函数
if (socket->waitForConnected()) {
// 连接成功
qDebug() << "Connected to server!";
} else {
// 连接失败
qDebug() << "连接失败";
}
Qt 服务端被连接后接收显示并接收消息:
connect(&server, &QTcpServer::newConnection, this, [=]() {
so = server.nextPendingConnection();
QString ip = so->peerAddress().toString();
quint16 port = so->peerPort();
qDebug() << "New connection from " << ip << ":" << port;
QString m = "<font color='blue'>有新的连接来自"+ip+":"+QString::number(port)+"</font>";
ui->SeverState->append(m);
//被连接后接收信息:
connect(so, &QTcpSocket::readyRead, this, [=]() {
QDateTime currentDateTime = QDateTime::currentDateTime();
QString ip = so->peerAddress().toString();
QByteArray data = so->readAll();//获取消息
qDebug() << "Received data:" << data;
QString mag1 = QString::fromUtf8(data);
qDebug()<<currentDateTime;
QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+mag1+"</font>";
ui->talk->append(mag);
});
});
Qt 发送消息:
主要通过QTcpSocket的write()函数进行发送消息。
void Widget::toSend(){
QString mag = this->ui->TextCin->toPlainText();
so->write(mag.toUtf8());
so->flush();
so->waitForBytesWritten();
socket->write(mag.toUtf8());
socket->flush();
socket->waitForBytesWritten();
QDateTime currentDateTime = QDateTime::currentDateTime();
QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
QString smag = strDateTime+"向"+this->AimIp+"发送消息:"+mag;
ui->talk->append(smag);
ui->TextCin->clear();
}
最后:
这个东东只能进行简单的tcp通讯,而且要求连接的是同一局域网的两台设备才能进行交流,不过也的确是这样的,除非你有额外的设备什么的~
当然,如果你想整个QQ那种的东西出来的话,可以整个中间服务器,然后让不同的客户端都访问那个中间服务器,通过中间服务器进行交流~
成品:
链接:https://pan.baidu.com/s/1VqygMyjETYg5cRbLOvMbZQ?pwd=8rtr
提取码:8rtr