【Qt】Java与Qt通信之TCP图片传输
程序描述
使用Qt建立TCP Server,用Java建立TCP Client,Client发送本地图片文件给Server,Server端使用Qt的QPixmap类显示在QLabel实例的背景中。
核心代码
- Java端:
Main.java
Java
import java.io.*;
import java.net.Socket;
public class Main {
public static void main(String[] args) {
Socket s;
File sendFile = new File("F:/Image/test8.png");
long fileSize = sendFile.length();
if(!sendFile.exists()) {
System.out.println("Cannot find the file");
return;
}
//定义文件输入流,用于打开、读取文件
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(sendFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//使用OutputStream向Socket发送数据
OutputStream outputStream = null;
//使用InputStream从Socket接收数据
InputStream inputStream = null;
/*建立客户端,连接服务器*/
try {
s = new Socket("127.0.0.1", 8899);
outputStream = s.getOutputStream();
int size = 0;
byte[] buffer = new byte[(int) fileSize];
while((size = fileInputStream.read(buffer)) != -1) {
System.out.println("Data size: \t" + size);
outputStream.write(buffer, 0, size);
outputStream.flush();
}
//接收服务器反馈信息,等待数据传输结果确认
while(true) {
inputStream = s.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(inputStreamReader);
String str = br.readLine();
System.out.println("Server: \t" + str);
/*不能使用 (str == "ok") 判断,因为str是String类型的,
"ok"是字符串数组,直接用==进行比较是不相等的*/
if (str.equals("ok")) {
break;
}
}
} catch (IOException e) {
System.out.println("Cannot connect the Server.");
e.printStackTrace();
}
}
}
- Qt端
mainwindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
// 2.添加头文件
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
// 4.添加信号槽
public slots:
void slotNewConnection();
void slotReceiveData();
void slotSocketDisconnect();
private slots:
void on_startServerBtn_clicked();
private:
Ui::MainWindow *ui;
// 3.添加成员 TCP Server和TCP Socket
QTcpServer *myServer;
QTcpSocket *mySocket;
};
#endif // MAINWINDOW_H
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//初始化GUI组件
ui->imgShowLabel->setScaledContents(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_startServerBtn_clicked()
{
//5.按钮事件
ui->startServerBtn->setText("Listening...");
ui->startServerBtn->setEnabled(false);
this->myServer = new QTcpServer(this);
this->myServer->listen(QHostAddress::Any, 8899);
//连接myServer的newConnection()信号与MainWindow的槽函数slotNewConnection()
connect(this->myServer, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
}
void MainWindow::slotNewConnection()
{
//使用mySocket接收客户端连接(这里只允许考虑一个连接的情况)
this->mySocket = this->myServer->nextPendingConnection();
//更新GUI
ui->startServerBtn->setText("Client Connected.");
//监听socket连接状态,准备接收数据
//连接信号与槽
connect(this->mySocket, SIGNAL(readyRead()), this, SLOT(slotReceiveData()));
connect(this->mySocket, SIGNAL(disconnected()), this, SLOT(slotSocketDisconnect()));
//控制台输出"Client connected success."
qDebug()<<"Client connected success.";
}
void MainWindow::slotReceiveData()
{
qDebug()<<"Start receive data from Client...";
QByteArray bytes = NULL;
while(this->mySocket->waitForReadyRead(100))
{
qDebug()<<"Data receiving...";
bytes.append(this->mySocket->readAll());
}
//Send Back Data to Client
if(this->mySocket->isWritable())
{
//结尾中的'\n'表示数据发送完毕
QString sendData = "ok\n" ;
this->mySocket->write(sendData.toStdString().c_str(), strlen(sendData.toStdString().c_str()));
}
else
{
qDebug()<<"Cannot send back data to Client.";
}
QPixmap pixmap;
pixmap.loadFromData(bytes);
//显示到GUI中
ui->imgShowLabel->setPixmap(pixmap);
}
void MainWindow::slotSocketDisconnect()
{
this->mySocket->close();
ui->startServerBtn->setText("Listening...");
qDebug()<<"Socket disconnected";
}
###GUI展示