QT(传视频的雏形,连续传图片)

一、学到的东西:

1、gcc *.c可以同时编译当前文件夹下的所有文件

 

二、客户端代码:

1、设计界面:

2、.pro

QT += core gui QT += network QT += core greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ widget.cpp HEADERS += \ widget.h FORMS += \ widget.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target

 

3、widget.h

#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpSocket> #include <QPixmap> #include <QTimer> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_pushButton_clicked(); void net_success(); void pic_recv(); void on_pushButton_2_clicked(); private: Ui::Widget *ui; QTcpSocket *socket; QTimer *tm; int piclen; char picbuf[500*1024]; }; #endif // WIDGET_H

 

4、widget.cpp

#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); socket = NULL; tm = NULL; ui->label->setScaledContents(true);//自适应图片大小 } Widget::~Widget() { delete ui; } void Widget::on_pushButton_clicked() { if(NULL == socket) { //建立QTcpSocket类的对象 socket = new QTcpSocket(); //connectToHost函数就是将ip,端口号信息存入后和服务器创建连接,创建后socket将不再会是NULL。 socket->connectToHost(ui->lineEdit->text(),ui->lineEdit_2->text().toInt()); //建立QTimer类的对象 tm = new QTimer(); } //将信号函数connected与net_success()绑定,一但连接成功就执行net_success()函数 connect(socket,SIGNAL(connected()),this,SLOT(net_success()));//connected()表示连接成功返回的信号 connect(tm, SIGNAL(timeout()), this, SLOT(pic_recv())); } void Widget::net_success() { ui->pushButton->setEnabled(false);//a按钮失效 } void Widget::pic_recv() { socket->write("pic",4);//向服务器发一条消息,表示需要传图片。 char len[10] = {0}; socket->read(len,10); piclen = atoi(len); socket->read(picbuf,piclen);//在读取的时候直到读取piclen长的内容后才进入下一步 QPixmap pix; //loadFromData函数就是将图片的信息存入(内容,大小,后缀名)pix对象里面。 pix.loadFromData((uchar *)picbuf,piclen,"jpg"); //setPixmap函数就是将图片显示在label内。 ui->label->setPixmap(pix); } void Widget::on_pushButton_2_clicked() { tm->start(1000);//打开定时器1S触发一次而且一旦开启,需要主动去关闭不然一直计时 }

三、服务器代码:

1、main.c:

#include "ser.h" int pic_send(int fd); int main() { int fd = tcp_server_init("0.0.0.0", 8888, 10); if(-1 == fd){ perror("init"); return -1; } int nfd = tcp_wait_connect(fd); if(-1 == nfd){ perror("wait"); return -1; } char cmd[4]; while(1){ read(nfd, cmd, 4); if(0 == strncmp(cmd, "pic", 3)){ pic_send(nfd); }else{ return -1; } } } int pic_send(int fd) { static int id = 1; if(4 == id){ id = 1; } char name[10]; sprintf(name, "%d.jpg", id); int rfd = open(name, O_RDONLY); if(-1 == rfd){ return -1; } char buf[500*1024], pic_len[10]; int piclen = 0, ret; while(1){ ret = read(rfd, buf+piclen, 1024); if(0 == ret){ break; } piclen += ret; } sprintf(pic_len,"%d", piclen); write(fd, pic_len, 10); write(fd, buf, piclen); id++; }

2、ser.c

#include "ser.h" //tcp server相关函数 int tcp_server_init(char *ip, int port, int backlog) { int fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == fd){ return -1; } struct sockaddr_in sddr; sddr.sin_family = AF_INET; sddr.sin_port = htons(port); sddr.sin_addr.s_addr = inet_addr(ip); if(-1 == bind(fd, (void *)&sddr, sizeof(sddr))){ return -1; } if(-1 == listen(fd, backlog)){ return -1; } puts("listen...."); return fd; } int tcp_wait_connect(int fd) { struct sockaddr_in cddr; int len = sizeof(cddr); int nfd = accept(fd, (void *)&cddr, &len); if(-1 == nfd){ return -1; } printf("IP:%sPORT:%d connected!\n", inet_ntoa(cddr.sin_addr), ntohs(cddr.sin_port)); return nfd; }

3、ser.h

#ifndef _SER_H #define _SER_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> //tcp server相关函数 int tcp_server_init(char *ip, int port, int backlog); int tcp_wait_connect(int fd); #endif

四、注意:

1、在服务器文件夹下需要有图片文件,当前代码为.jpg文件。

 


__EOF__

本文作者西北小蚂蚁
本文链接https://www.cnblogs.com/JinShanCheShen/p/15045709.html
关于博主:山不向我走来,我便向他走去!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   西北小蚂蚁  阅读(421)  评论(1编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示