欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 基于QT的实现TCP的网络通信(服务器端)

基于QT的实现TCP的网络通信(服务器端)

2024/12/22 16:01:58 来源:https://blog.csdn.net/BEIFEN13/article/details/141093374  浏览:    关键词:基于QT的实现TCP的网络通信(服务器端)

首先介绍一下TCP,UDP的特点:

TCP是面向连接的流式传输协议,UDP是面向无连接的报式传输协议

TCP(传输控制协议)和UDP(用户数据报协议)

TCP(传输控制协议)

  • 面向连接:在数据传输之前,TCP会建立一条可靠的连接,以确保数据的有序传输。
  • 流式传输:TCP将数据视为连续的字节流,不保留数据报边界。

-----流式传输协议是一种用于在网络上传输连续数据流的协议。它允许数据以一种连续的、类似于流水的方式进行传输,而不是 以离散的数据包形式进行传输。

a连续性:流式传输协议将数据视为一个连续的流,而不是独立的数据包。这意味着数据可以以一种不间断的方式进行传输,从而减少了传输延迟。

b实时性:由于数据是连续传输的,流式传输协议适用于实时性要求较高的应用,如音频和视频流媒体。

c顺序性:流式传输协议通常要求数据按照正确的顺序进行传输,以确保数据的完整性和准确性。

d可靠性:为了保证数据的可靠性,流式传输协议通常采用一些机制,如错误检测和纠正、重传等。

  • 可靠性:TCP通过确认、重传和超时机制来保证数据的可靠传输。
  • 有序性:TCP确保数据以正确的顺序到达目的地。
  • 流量控制:TCP使用滑动窗口机制来控制发送方的发送速度,以避免接收方的缓冲区溢出。
  • 拥塞控制:TCP使用拥塞控制算法来避免网络拥塞,并根据网络状况调整发送速率。

UDP(用户数据报协议)

  • 面向无连接:UDP不建立连接,直接将数据报发送到目的地,不保证数据的有序传输。
  • 报式传输:UDP保留数据报的边界,将数据划分为独立的数据报进行传输。
  • 不可靠性:UDP不保证数据的可靠传输,不进行确认、重传和超时处理。
  • 无序性:UDP不保证数据的有序到达,接收方可能收到乱序的数据报。
  • 无流量控制:UDP不进行流量控制,发送方可以以任意速度发送数据报。
  • 无拥塞控制:UDP不进行拥塞控制,不根据网络状况调整发送速率。

TCP和UDP是两种不同的传输层协议,它们在可靠性、有序性、流量控制和拥塞控制等方面存在差异。TCP适用于对可靠性要求较高的应用,如文件传输和远程登录;而UDP适用于对实时性要求较高的应用,如语音通信和视频流传输。

QT服务器端

窗口搭建

首先在QT中新建一个项目,基类为Qmainwindow

  然后在mainwindow.ui中完成以下窗口的搭建

 要在在mainwindow.ui中实现以下窗口

首先在最上端放一个QWidget在里面放入Qlabel输入端口QLineEditObjectnameport表示输入的端口号,再放一个QPushbutton输入监听ObjectnamesetListen

 然后在下面放一个QGroupBox,name改为历史信息表示服务器客户端发送的信息都会保存在这,在里面放一个TextEdit,Objectname改为record再水平布局

下面类似,TextEditObjectname改为msg表示服务器要发送的信息,每次点击发送清空发送的信息框中的内容

最下面还是先放一个QGroupBox,中间放一个pushbutton输入发送,Objectname改为sendMsg,再水平布局

最后整体 垂直布局,这样服务器的窗口就搭建成功了

代码部分

首先,要想在QT中完成TCP的传输协议,不论是客户端还是服务器我们都先要在QtSever.pro中的

QT += core gui 后加入 network如图

mianwindow.h

 在mainwindow.h中,我们要加入如图所示头文件,并创建两个指针类型的QTcpSever和QTcpSocket类的对象,*m_s,和*tcp;

这里的slots内的是槽函数,我们可以右键ui中的按钮转到槽函数,可以自动在头文件中定义;

mainwindow.cpp

 首先在构造函数中默认端口号是8899;

  设置窗口的标题是服务器

首先实例化QTcpsever类,m_s;

如果客户端那边发来一个连接请求,m_s就会收到一个newConnection的信号,这里实现一个匿名函数  用QTcpSever类的nextPendingConnction函数返回套接字tcp 

如果客户端有内容发送过来,tcp就会收到一个readyRead的信号,定义一个QByteAttay的data的数据类型去接受发送来的内容,把读到的内容追加到record文本框中

如果客户端断联,tcp会收到disconncet的信号,使用匿名函数进行tcp的关闭close()和资源释放deleteLater()

实现头文件中的两个槽函数,如果点击sectListen,会将窗口中port文本框的内容赋值给一个unsined short 类型 的port,   再使用QTcpSever类中的listen监听客户端发送的ip和端口号;

如果此时正在监听那么就将监听按钮设置为不可按的状态

如果点击sendMsg,首先窗口中的msg赋值给Qstring类型的msg,tcp里的write函数发送给客户端,这时窗口的record就可以进行文本追加操作了,记录服务器发送的文本

那么到这里操作就写完了,以下是。h和.cpp的完整代码

服务器完整代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include<QTcpServer>
#include <QTcpSocket>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_setListen_clicked();void on_sendMsg_clicked();private:Ui::MainWindow *ui;QTcpServer *m_s;QTcpSocket *tcp;};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);ui->port->setText("8899");setWindowTitle("服务器");m_s = new QTcpServer(this);//实例化connect(m_s,&QTcpServer::newConnection,this,[=](){//如果收到客户端的连接,就tcp = m_s->nextPendingConnection();//返回套接字用于通信的 tcpconnect(tcp,&QTcpSocket::readyRead,this,[=](){//如果tcp收到一个readyRead信号就QByteArray data = tcp->readAll();//把内容读出来放到data里ui->record->append("客户端say:" + data);//把内容追加到record中});connect(tcp,&QTcpSocket::disconnected,this,[=](){//如果套接字收到断联消息,就关闭套接字并释放tcp->close();tcp->deleteLater();}) ;});
}
MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_setListen_clicked()
{unsigned short port = ui->port->text().toUShort();m_s->listen(QHostAddress::Any,port);ui->setListen->setDisabled(true);
}void MainWindow::on_sendMsg_clicked()
{QString msg = ui->msg->toPlainText();tcp->write(msg.toUtf8());ui->record->append("服务器say:" + msg);
}
main.cpp
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

最后编译的效果

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com