QT使用TCP传输图像或者数据的方法
客户端QTCPsocket使用方法 加qmake到工程pro:把 Qtcpsocket用到的qmake 也就是 network 加到我们原来的pro文件中
QT+= core gui network
同时也不要忘记包含头文件
#include
然后在类里面创建一个指针变量,不要忘记在构造函数中new一下哦,指针不同于普通变量,我们需要new一下为他分配地址空间的。
QTcpSocket *tcpsocket;
tcpsocket = new QTcpSocket(this);
连接主机,注意连接主机的参数有两个,第一个是主机IP,我这里用sendip代替,第二个是端口号,端口号在0-65535之间,但是我们尽可能的用10000以上的,因为1000以内的端口多半都被使用了,容易产生冲突。
tcpsocket->connectToHost(sendip,48797);
如果我们传输的是图片的话,图片太大我们就要首先压缩图片,这里的例子来源于摄像头接收图片的槽函数,根据自己的需要自行裁剪,这就能体现嵌入式的可裁剪性了,整体代码一并奉上:
connect(ui->camear,SIGNAL(receiveImage(QImage)),this,SLOT(slotCremasend(QImage)));
//链接信号槽
void TinyUi::slotCremasend(QImage image)
{
if(tcpsocket->state() == QAbstractSocket::ConnectedState){//如果连接上再进行传输,避免bugQPixmap pixmap = QPixmap::fromImage(image);
//把img转成位图,我们要转成jpg格式
QByteArray ba;
QBuffer buf(&ba);
//把ba绑定到buf上,操作buf就等于操作bapixmap.save(&buf,"jpg",50);
//把pixmap保存成jpg,压缩质量50 数据保存到buf
//先写大小过去,告诉主机我们要传输的数据有多大
tcpsocket->write(QString("size=%1").arg(ba.size()).toLocal8Bit().data());
tcpsocket->waitForReadyRead();
//等待主机响应“ok”
tcpsocket->write(ba);
//把图像数据写入传输给主机
tcpsocket->waitForReadyRead();
//等待主机响应第二个“ok”
}
}
哎呀一不小心把所有代码都放上来了,那么到这里呢,TCP从机给主机发送就基本完成了。
哦对了,注意注意,这里断开与主机的连接不能直接 :
tcpsocket->disconnect();
//错误的断开方式,这是断开服务器的意思,下一次就连接不上了
【QT使用TCP传输图像或者数据的方法】正确的断开方式应该是这样的
tcpsocket->disconnectFromHost();
//正确的断开方式应该是断开与主机的连接,切记!
服务器QTCPserver的使用 因为QTCPsever和QTCPsocket是不同的两个工程,所以我们也要重复做这个,加qmake到工程pro:把 Qtcpsocket用到的qmake 也就是 network 加到我们原来的pro文件中
QT+= core gui network
同时也不要忘记包含头文件
#include
#include
一样的方法创一个指针:
QTcpServer *tcpserver;
QTcpSocket *tcpsocket;
注意:这里只需要new tcpserver就可以了,不用new tcpsocket 因为tcpsocket是用来获取连接成功后的socket
tcpserver = new QTcpServer(this);
主机连接从机是采用监听的方式,一般监听的对象设成Any,你也可以根据自己网络情况设成AnyIPv4或者AnyIPv6,但是端口号一定要和我们从机写的端口号一致才能通信成功。代码如下,:
tcpserver->listen(QHostAddress::Any,48797);
监听到的时候我们用连接到信号槽来处理连接成功,提醒一点就是连接信号槽的connect写到构造函数中去:
连接信号槽:
connect(tcpserver,SIGNAL(newConnection()),this,SLOT(slotTcpNewConnection()));
信号槽函数:
void mastermain:: slotTcpNewConnection()
{
qDebug("NEW CONNECTION");
tcpsocket = tcpserver->nextPendingConnection();
//获取监听到的socket
//连接成功后我们再连接一个信号槽到准备接收信号槽函数中去
connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(slotTcpReadyRead()));
}
接收槽函数主要是用来接收从机传输过来的数据,话不多说,直接上代码:
void mastermain::slotTcpReadyRead()
{
QByteArray buf = tcpsocket->readAll();
if(buf.contains("size=")){//contain是判断字符串是否含有某关键字//"size=30711"的30711怎么弄出来
//方法1:直接把size=这个字符串删掉
buf = buf.replace("size=","");
totalsize = buf.toInt();
//定义一个变量来接收数据大小,用于下面比较jpgArr.clear();
tcpsocket->write("ok");
//发送一个响应给客户机
tcpsocket->waitForBytesWritten();
//等待数据写入}else{
jpgArr.append(buf);
//如果不是图片大小数据,就是图片数据,图片数据追加写到数组里面
}if(jpgArr.length() == totalsize){img->loadFromData(jpgArr,"JPG");
//从jpgArr中读数据,类型为JPG
pixmap->convertFromImage(*img);
//img转成pixmap,因为QLable只能显示pixmapui->screenlab->setPixmap(*pixmap);
jpgArr.clear();
tcpsocket->write("ok");
}
}
到这里呢就完成TCP通信,感谢阅读哦,小编也是初出江湖,希望将自己平时学习到的一些东西实时记录下来并分享给大家,如果觉得还不错的话谢谢点赞收藏啦,也可以私聊小编一起交流学习。
推荐阅读
- CVE-2020-16898|CVE-2020-16898 TCP/IP远程代码执行漏洞
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用