QT/C++——网络编程

1年前未命名204
QT/C++——网络编程 宇努力学习 于2023-02-01 18:21:32发布 1007 收藏 10 分类专栏: C++/QT 网络编程 文章标签: c++ QT 网络编程 TCP UDP C++/QT 同时被 2 个专栏收录 9 篇文章 0 订阅 订阅专栏 网络编程 11 篇文章 0 订阅 订阅专栏

目录

一、基础知识复习

二、UDP

客户端:

服务器:

三、TCP

服务器:

客户端:

四、小项目

客户端:

服务器:


一、基础知识复习

这部分内容前面讲的比较详细,现在就是简单复习一下。

两台主机之间通信要经过封包他有一堆包头

 

TCP、UDP都是基于套接字,C写我感觉已经挺简单了,老师说C++更简单,我们往下学学看。

二、UDP

网络编程这块要在工程文件中加上network

服务器是被动套接字,客户端是主动套接字

客户端: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTextEdit> #include <QLineEdit> #include <QPushButton> #include <QUdpSocket> #include <QHostAddress> class Widget : public QWidget { Q_OBJECT public slots: void senddata() { udpsock->writeDatagram(le->text().toStdString().c_str(), QHostAddress("192.168.3.27"), 8888); } void recvdata() { QByteArray datagram; datagram.resize(udpsock->pendingDatagramSize()); QHostAddress sender; quint16 senderPort; udpsock->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); te->append(datagram); } public: Widget(QWidget *parent = 0); ~Widget(); private: QTextEdit *te; QLineEdit *le; QPushButton *pb; QUdpSocket *udpsock; }; #endif // WIDGET_H #include "widget.h" #include <QVBoxLayout> Widget::Widget(QWidget *parent) : QWidget(parent) { te = new QTextEdit; le = new QLineEdit; pb = new QPushButton("send"); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(te); vbox->addWidget(le); vbox->addWidget(pb); setLayout(vbox); udpsock = new QUdpSocket; connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata())); connect(udpsock, SIGNAL(readyRead()), this, SLOT(recvdata())); } Widget::~Widget() { } 服务器: #ifndef UDPSERVER_H #define UDPSERVER_H #include <QObject> #include <QUdpSocket> #include <QDebug> class udpServer : public QObject { Q_OBJECT public: explicit udpServer(QObject *parent = 0); void init() { udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::AnyIPv4, 8888); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); qDebug()<<"init...."; } signals: public slots: void readPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); QHostAddress sender; quint16 senderPort; udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); //processTheDatagram(datagram); qDebug()<<"recv: "<<datagram; udpSocket->writeDatagram(datagram.data(), datagram.size(), sender, senderPort); } } private: QUdpSocket *udpSocket; }; #endif // UDPSERVER_H

两个程序的工程文件中一定要加入network

三、TCP

服务器: #ifndef TCPSERVER_H #define TCPSERVER_H #include <QObject> #include <QTcpServer> #include <QTcpSocket> #include <QDebug> class tcpServer : public QObject { Q_OBJECT public: explicit tcpServer(QObject *parent = 0); signals: public slots: void newconnected() { qDebug()<<"connected"; clientsock = ser->nextPendingConnection(); connect(clientsock, SIGNAL(readyRead()), this, SLOT(readdata())); } void readdata() { QByteArray buf = clientsock->readAll(); qDebug()<<"recv: "<<buf; clientsock->write(buf); } private: QTcpServer *ser; QTcpSocket *clientsock; }; #endif // TCPSERVER_H #include "tcpserver.h" #include <QHostAddress> tcpServer::tcpServer(QObject *parent) : QObject(parent) { ser = new QTcpServer; ser->listen(QHostAddress::AnyIPv4, 8888); connect(ser, SIGNAL(newConnection()), this, SLOT(newconnected())); ser->waitForNewConnection(); } 客户端: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTextEdit> #include <QLineEdit> #include <QPushButton> #include <QTcpSocket> class Widget : public QWidget { Q_OBJECT public slots: void senddata() { tcpsocket->write(le->text().toStdString().c_str()); } void recvdata() { QByteArray buf = tcpsocket->readAll(); te->append(buf); } public: Widget(QWidget *parent = 0); ~Widget(); private: QTextEdit *te; QLineEdit *le; QPushButton *pb; QTcpSocket *tcpsocket; }; #endif // WIDGET_H #include "widget.h" #include <QVBoxLayout> #include <QHostAddress> Widget::Widget(QWidget *parent) : QWidget(parent) { te = new QTextEdit; le = new QLineEdit; pb = new QPushButton("send"); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(te); vbox->addWidget(le); vbox->addWidget(pb); setLayout(vbox); tcpsocket = new QTcpSocket; //connect to server tcpsocket->connectToHost(QHostAddress("192.168.3.27"), 8888); connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata())); connect(tcpsocket, SIGNAL(readyRead()), this, SLOT(recvdata())); } Widget::~Widget() { } 四、小项目

实现一个类似于监控的东西

就是把传输内容换成了照片

客户端: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QLabel> #include <QLineEdit> #include <QTcpSocket> #include <QPushButton> #include <QHostAddress> #include <QDebug> #include <QPixmap> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); public slots: void startv() { readsize = true; sockv = new QTcpSocket(this); connect(sockv, SIGNAL(readyRead()), this, SLOT(recv_show())); sockv->connectToHost(QHostAddress(leip->text()), atoi(leport->text().toStdString().c_str())); btstart->setText("STOP"); leip->setDisabled(true); leport->setDisabled(true); disconnect(btstart, SIGNAL(clicked()), this, SLOT(startv())); connect(btstart, SIGNAL(clicked()), this, SLOT(stop())); } void stop() { sockv->close(); sockv->deleteLater(); disconnect(btstart, SIGNAL(clicked()), this, SLOT(stop())); connect(btstart, SIGNAL(clicked()), this, SLOT(startv())); leip->setDisabled(false); leport->setDisabled(false); btstart->setText("START"); } void recv_show() { if(readsize){ //接收图片大小 char buf[10] = {0}; sockv->read(buf, 10); picsize = atoi(buf); //转成整形大小值 // qDebug()<<picsize; readsize = false; } else { if(sockv->bytesAvailable() < picsize) //等待图片内容接收完整 return; char buf[640*480*3]; sockv->read(buf, picsize); QPixmap pix; pix.loadFromData((uchar*)buf, picsize, "jpeg"); lbvideo->setPixmap(pix);//切换照片 readsize = true; } } private: QLabel *lbvideo, *lbip, *lbport; QLineEdit *leip, *leport; QPushButton *btstart; QTcpSocket *sockv; bool readsize; int picsize; }; #endif // WIDGET_H #include "widget.h" #include <QHBoxLayout> #include <QVBoxLayout> Widget::Widget(QWidget *parent) : QWidget(parent) { lbvideo = new QLabel; lbvideo->setFixedSize(640,480); lbvideo->setScaledContents(true); lbip = new QLabel("IP"); lbport = new QLabel("PORT"); leip = new QLineEdit("192.168.3.27"); leport = new QLineEdit("8888"); btstart = new QPushButton("START"); QHBoxLayout *hbox = new QHBoxLayout; hbox->addWidget(lbip); hbox->addWidget(leip); hbox->addWidget(lbport); hbox->addWidget(leport); hbox->addWidget(btstart); QVBoxLayout *vbox = new QVBoxLayout; vbox->addLayout(hbox); vbox->addWidget(lbvideo); setLayout(vbox); connect(btstart, SIGNAL(clicked()), this, SLOT(startv())); } Widget::~Widget() { } 服务器: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QCamera> #include <QCameraViewfinder> #include <QCameraImageCapture> #include <QLabel> #include <QTimerEvent> #include <QDebug> #include <QPixmap> #include <QTcpServer> #include <QTcpSocket> #include <QTemporaryFile> #include <QFile> #include <QBuffer> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); public slots: void show_pic(int i, QImage img) { QPixmap pix(1920, 1080); #if 1 pix.fill(Qt::red); pix = pix.fromImage(img); lb_pic->setPixmap(pix); #else lb_pic->setPixmap(QPixmap::fromImage(img)); #endif // qDebug()<<i; if(client&&client->isWritable()) { // qDebug()<<"sending "<<pix.size(); #if 0 pix.save("tem.jpg","jpeg"); // qDebug()<<"saveed"; QFile tem("tem.jpg"); tem.open(QIODevice::ReadOnly); #else QBuffer tem; pix.save(&tem, "jpeg"); #endif char buf[10] = {0}; // qDebug()<<"size: "<<buf; sprintf(buf, "%d", tem.size()); // qDebug()<<"size: "<<buf; client->write(buf, 10);//发大小(大小值先转换成字符串装在固定的10个字节的buff中发送) // qDebug()<<"size ok"; #if 0 QByteArray data = tem.readAll(); #else QByteArray data(tem.buffer()); #endif client->write(data);//发图片内容 // qDebug()<<"finish"; tem.close(); } } void accept_client() { if(NULL != client) { client->close(); client->deleteLater(); } client = myserver->nextPendingConnection(); connect(client, SIGNAL(disconnected()), this, SLOT(client_close())); } void client_close() { client->close(); client->deleteLater(); client = NULL; } protected: virtual void timerEvent(QTimerEvent *event) { imageCapture->capture(); // qDebug()<<"tttt"; } private: QCamera *camera; QCameraViewfinder *viewfinder; QCameraImageCapture *imageCapture; QLabel *lb_pic; QTcpServer *myserver; QTcpSocket *client; }; #endif // WIDGET_H #include "widget.h" #include <QHBoxLayout> #include <QHostAddress> Widget::Widget(QWidget *parent) : QWidget(parent) { camera = new QCamera("/dev/video0"); //"/dev/video0" 摄像头设备文件,视情况而定 viewfinder = new QCameraViewfinder(this); viewfinder->setFixedSize(640,480); viewfinder->show(); lb_pic = new QLabel(this); myserver = new QTcpServer(this); client = NULL; camera->setViewfinder(viewfinder); QHBoxLayout *hbox = new QHBoxLayout; hbox->addWidget(viewfinder); hbox->addWidget(lb_pic); this->setLayout(hbox); imageCapture = new QCameraImageCapture(camera); camera->setCaptureMode(QCamera::CaptureStillImage); connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(show_pic(int,QImage))); connect(myserver, SIGNAL(newConnection()), this, SLOT(accept_client())); this->startTimer(3); myserver->listen(QHostAddress::AnyIPv4, 8888); camera->start(); } Widget::~Widget() { }

---------------------------------------------------------------------------------------------------------------------------------

发文不通过只能写点”废话“了。学了一个星期的QT感觉其实不难,就是把一些封装好的类组合起来形成一些图形化界面。感觉还是挺好用,起码和C有相通性,唯一的难点应该在C++的语法上。所以会C++的同学应该更加的得心应手。挺好玩的,等学完驱动试试拿QT开发两个项目练练手。比如电视剧里男主给女主写的那个小猪闹钟,非常可爱以前不知道怎么下手做,学完QT我好像知道应该怎么写了。然后我还想做一个类似于QQ微信这种的聊天工具,可惜还不知道怎么用私网和私网通信。难道和女神之间搞点浪漫的东西还要租两台云服务器嘛,那也太扫兴了。现在这ip都是192.168开头的不能直接通信。听朋友说java有个内网透传技术是干这个的。不知道用C怎么实现。不过服务器我虽然买不起但是我打算自己买点件搭建一个服务器。应该会很有意思。

---------------------------------------------------------------------------------------------------------------------------------

标签: [db:标签TAG]

相关文章

用chatgpt写insar地质灾害的论文,重复率只有1.8%,chatgpt4.0写论文不是梦

用chatgpt写insar地质灾害的论文,重复率只有1.8%,chatgpt4.0写论文不是梦...

入职字节外包一个月,我离职了

入职字节外包一个月,我离职了...

[Python从零到壹] 六十四.图像识别及经典案例篇之图像傅里叶变换和傅里叶逆变换详解

[Python从零到壹] 六十四.图像识别及经典案例篇之图像傅里叶变换和傅里叶逆变换详解...

JAVA实现心跳检测【长连接】

JAVA实现心跳检测【长连接】...

带你走进API安全的知识海洋

带你走进API安全的知识海洋...

学习C++这几个网站足矣

学习C++这几个网站足矣...