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 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/JinShanCheShen/p/15045709.html
关于博主:山不向我走来,我便向他走去!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话