树莓派和上位机使用TCP通信(字符串和图像传输)
文章目录树莓派和上位机使用TCP通信系统介绍字符串通信树莓派具体实现代码:Qt具体实现代码:程序执行图像发送树莓派具体实现代码:Qt具体实现代码:程序执行树莓派和上位机使用TCP通信系统介绍下位机: 树莓派作为下位机,IP地址为192.168.199.206,作为tcp的客户端(c实现),通信端口号为8888,上位机: Ubuntu(虚拟机)作为上位机,作为tcp的服务端(Qt实现),Qt版本为5
·
树莓派和上位机使用TCP通信
系统介绍
下位机: 树莓派作为下位机,IP地址为192.168.199.206,作为tcp的客户端(c实现),通信端口号为8888,
上位机: Ubuntu(虚拟机)作为上位机,作为tcp的服务端(Qt实现),Qt版本为5.12,IP地址为192.168.199.149,通信端口为8888
注意:
- 该系统为单向通信,只能由客户端发送到服务端,发信数据类型为字符串或图像数据
- 此项目需要在Qt设计师中添加一个Label控件,用于显示文本和图像
字符串通信
树莓派具体实现代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])
{
int sockfd,numbytes;
char buf[BUFSIZ];
struct sockaddr_in their_addr;
while((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1);
printf("We get the sockfd~\n");
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(8888);
their_addr.sin_addr.s_addr=inet_addr("192.168.199.149");
bzero(&(their_addr.sin_zero), 8); //清空数据中前8位
while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
printf("Get the Server~Cheers!\n");
buf[numbytes]='\0';
while(1)
{
printf("Entersome thing:");
scanf("%s",buf);
numbytes = send(sockfd, buf, strlen(buf), 0);
}
close(sockfd);
return 0;
}
Qt具体实现代码:
Qt如果需要使用socket通信,需要在pro文件中添加以下语句:
QT += network
头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QTcpServer *tcpServer = new QTcpServer(); //Tcp服务端对象
QTcpSocket *tcpSocket = new QTcpSocket(); //Tcp连接socket
void initWindow(); //初始化窗体
void setNetwork(); //设置网络信息
private slots:
void serverNewConnect(); //新的网络连接响应
void serverReadData(); //服务端读取数据
void serverDisconnection(); //服务端断开连接
};
#endif // MAINWINDOW_H
实现文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
initWindow();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initWindow()
{
//初始化窗体
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(serverNewConnect()));
setNetwork();
}
void MainWindow::setNetwork()
{
//开启网络服务
int port = 8888; //Tcp端口号为8888
if(!tcpServer->listen(QHostAddress::Any, port))
{
qDebug() << "服务器端监听失败!!!";
return;
}else
{
qDebug() << "服务器端监听成功!!!";
}
}
void MainWindow::serverNewConnect()
{
//服务端新连接槽函数
tcpSocket = tcpServer->nextPendingConnection();
if(!tcpSocket)
{
qDebug() << "未能成功获取客户端连接!!!";
}else
{
qDebug() << "成功建立连接!!!";
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(serverReadData()));
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(serverDisconnection()));
}
}
void MainWindow::serverReadData()
{
//服务器接收数据函数
ui->label->setText((QString)tcpSocket->readAll());
}
void MainWindow::serverDisconnection()
{
//服务端断开连接
qDebug() << "与客户端断开连接!!!";
return;
}
程序执行
- 打开上位机中Qt程序,使得服务器监测客户端的连接
- 执行客户端,可以看到服务端输出连接成功提示语句
- 在客户端中输入字符,以回车结束,服务端即可打印出相应字符
程序执行效果如下:
图像发送
树莓派具体实现代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAXSIZE 1024*1024
int main(int argc,char *argv[])
{
int sockfd,len;
char buffer[MAXSIZE];
struct sockaddr_in their_addr;
FILE *fq;
while((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1);
printf("We get the sockfd~\n");
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(8888);
their_addr.sin_addr.s_addr=inet_addr("192.168.199.149");
bzero(&(their_addr.sin_zero), 8);
while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
//需要确保当前目录下有相应图像文件
if((fq = fopen("./luo.jpg","rb") ) == NULL ){
printf("File open.\n");
close(sockfd);
exit(1);
}
while(!feof(fq)){
len = fread(buffer, 1, sizeof(buffer), fq);
printf("len is : %d\n", len);
if(len != write(sockfd, buffer, len)){
break;
}
}
close(sockfd);
fclose(fq);
return 0;
}
Qt具体实现代码:
Qt如果需要使用socket通信,需要在pro文件中添加以下语句:
QT += network
头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QBuffer>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QByteArray array; //图像文件
QTcpServer *tcpServer = new QTcpServer(); //Tcp服务端对象
QTcpSocket *tcpSocket = new QTcpSocket(); //Tcp连接socket
void initWindow(); //初始化窗体
void setNetwork(); //设置网络信息
private slots:
void serverNewConnect(); //新的网络连接响应
void serverReadData(); //服务端读取数据
void serverDisconnection(); //服务端断开连接
};
#endif // MAINWINDOW_H
实现文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
initWindow();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initWindow()
{
//初始化窗体
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(serverNewConnect()));
setNetwork();
}
void MainWindow::setNetwork()
{
//开启网络服务
int port = 8888; //Tcp端口号为8888
if(!tcpServer->listen(QHostAddress::Any, port))
{
qDebug() << "服务器端监听失败!!!";
return;
}else
{
qDebug() << "服务器端监听成功!!!";
}
}
void MainWindow::serverNewConnect()
{
//服务端新连接槽函数
tcpSocket = tcpServer->nextPendingConnection();
if(!tcpSocket)
{
qDebug() << "未能成功获取客户端连接!!!";
}else
{
qDebug() << "成功建立连接!!!";
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(serverReadData()));
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(serverDisconnection()));
}
}
void MainWindow::serverReadData()
{
//服务器接收数据函数
array.append((QByteArray)tcpSocket->readAll());
}
void MainWindow::serverDisconnection()
{
//服务端断开连接
qDebug() << "与客户端断开连接!!!";
QBuffer buffer(&array);
buffer.open(QIODevice::ReadOnly);
QPixmap picture;
picture.loadFromData(array, "jpg");
ui->label->setPixmap(picture);
return;
}
程序执行
- 打开上位机中Qt程序,使得服务器监测客户端的连接
- 执行客户端,可以看到服务端输出连接成功提示语句(首先需要确保在客户端路径下有相应图像文件)
- 在客户端会输出图像文件尺寸,在服务端会将图像展示到label控件中
执行效果如下:
更多推荐
已为社区贡献2条内容
所有评论(0)