QT使用Socket与安卓Socket互发消息

news2024/11/22 15:58:47

背景:安卓设备通过usb网络共享给Linux,此时安卓设备与linux处于同一网络环境,符合使用socket的条件,linux做客户端,安卓做服务端

1.QT使用Socket

(1).在工程文件中加入

QT += network

(2).导包以及写一些槽函数用做数据传输与状态接收

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtNetwork/QTcpSocket>
#include <QMainWindow>
#include <QTcpServer>
#include "QTimer"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


public slots:
    //用做读取服务端发送的数据
    void readData();
    //获取当前socket的连接状态
   void displayError(QAbstractSocket::SocketError);


private:
    Ui::MainWindow *ui;
    QTcpSocket *socket;
};

#endif // MAINWINDOW_H

(3).实现Socket的数据互发与接收

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QFile"
#include "QTextCodec"
#include "QDebug"
#include "QFontDatabase"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    socket = new QTcpSocket(this);


    socket->abort();
    //这个地方是重点,因为安卓端我没有设置ip,那么这里的ip就是USB共享所分配的ip,可以进入安卓端使用ifconfig获取到ip地址
    //端口9999是我在安卓服务端设置的,等会安卓端代码会有写
    socket->connectToHost("192.168.XXX",9999);
    

    connect(socket, &QTcpSocket::readyRead, this, &MainWindow::readData);
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
                  this, SLOT(displayError(QAbstractSocket::SocketError)));
}


void MainWindow::readData() {
    qDebug() << "******************************clein====********************************";
    QString data = socket->readAll();
    QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    QString strData = codec->toUnicode(data.toUtf8());
    qDebug() << "readData message==="<<strData; // 输出 "11111"
    qDebug() << "******************************clein********************************\n";


    /*******************************读取到数据以后自动发送数据给服务端**********************************/
    // 用于暂存要发送的数据
    QString datas = "on_pushButton_2_clicked"; // 要发送的数据

    // 将数据转换为 UTF-8 编码
    QTextCodec* codecs = QTextCodec::codecForName("UTF-8");
    QByteArray utf8Data = codecs->fromUnicode(datas);
    // 发送数据
    socket->write(utf8Data);
    socket->flush();

}

void MainWindow::displayError(QAbstractSocket::SocketError)
 {
     qDebug() << "displayError error===="<<socket->errorString();
 }


MainWindow::~MainWindow()
{
    delete ui;
}

到这里QT代码就写完了,接下来我们看一下安卓端的发送与接收:

 2.安卓使用Socket,直接上服务端代码(Kotlin)

package com.jk.rtk

import android.content.Context
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.os.Build
import android.util.Log
import java.io.IOException
import java.io.InputStream
import java.io.OutputStreamWriter
import java.net.*
import java.util.*


object SocketServer {

    private val TAG = SocketServer::class.java.simpleName

    var SOCKET_PORT = 9999

    private var socket: Socket? = null
    private var serverSocket: ServerSocket? = null

    private lateinit var mCallback: ServerCallback


    var result = true
    /**
     * 开启服务
     */
    fun startServer(callback: ServerCallback): Boolean {
        Log.i(TAG, "startServer: ")
        mCallback = callback
        Thread {
            try {
                serverSocket = ServerSocket(SOCKET_PORT)
                while (result) {
                    socket = serverSocket?.accept()
                    mCallback.otherMsg("${socket?.inetAddress} to connected")
                    ServerThread(socket!!, mCallback).start()
                }
            } catch (e: IOException) {
                e.printStackTrace()
                result = false
            }
        }.start()
        return result
    }

    /**
     * 关闭服务
     */
    fun stopServer() {
        Log.i(TAG, "stopServer: ")
        socket?.apply {
            //shutdownInput()
            //shutdownOutput()
            close()
        }
        serverSocket?.close()
    }

    /**
     * 发送到客户端
     */
    fun sendToClient(msg: String) {
        Thread {
            if (socket!!.isClosed) {
                Log.e(TAG, "sendToClient: Socket is closed")
                return@Thread
            }
            Log.e(TAG, "sendToClient: msg====$msg")
            try {
                val out = OutputStreamWriter(socket!!.getOutputStream(), "UTF-8")
                out.write(msg)
                out.flush()
                mCallback.otherMsg("toClient: $msg")
                Log.d(TAG, "发送到客户端成功")
            } catch (e: IOException) {
                e.printStackTrace()
                Log.e(TAG, "向客户端发送消息失败")
            }
        }.start()
    }

    /*
    * 获取USB共享的ip地址
    * */
    fun getUsbTetheringIpAddress(): String? {
        try {
            val interfaces: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
            while (interfaces.hasMoreElements()) {
                val intf: NetworkInterface = interfaces.nextElement()
                val addresses = intf.interfaceAddresses
                for (addr in addresses) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        if (addr.networkPrefixLength >= 16 && !addr.address.isLinkLocalAddress) {
                            return addr.address.hostAddress
                        }
                    } else {
                        if (addr.address.isSiteLocalAddress && !addr.address.isLinkLocalAddress) {
                            return addr.address.hostAddress
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }




    class ServerThread(private val socket: Socket, private val callback: ServerCallback) :
        Thread() {

        override fun run() {
            val inputStream: InputStream?
            try {
                inputStream = socket.getInputStream()
                val buffer = ByteArray(1024)
                var len: Int
                var receiveStr = ""
                if (inputStream.available() == 0) {
                    Log.e(TAG, "inputStream.available() == 0")
                }
                while (inputStream.read(buffer).also { len = it } != -1) {
                    receiveStr += String(buffer, 0, len, Charsets.UTF_8).trim()
                    if (len < 1024) {
                        Log.e(TAG, "inputStream.receiveStr == $receiveStr")
                        callback.receiveClientMsg(true, receiveStr)
                        receiveStr = ""
                    }
                }
            } catch (e: IOException) {
                e.printStackTrace()
                e.message?.let { Log.e("socket error", it) }
                callback.receiveClientMsg(false, "")
            }
        }
    }
}

调用方式:这里用的java方式

(1).先启动服务 与回调函数

boolean isSocket = SocketServer.INSTANCE.startServer(new ServerCallback() {
                        @Override
                        public void receiveClientMsg(boolean success, @NonNull String msg) {
                            Log.e("TAG", "SocketServer receiveClientMsg success=" + success + "   msg=" + msg);
                            
                        }

                        @Override
                        public void otherMsg(@NonNull String msg) {
                            Log.e("TAG", "SocketServer otherMsg  msg=" + msg);
                            
                        }
                    });


(2).发送数据: SocketServer.INSTANCE.sendToClient("json");

 linux运行截图

安卓端运行截图

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1212983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pycharm安装库失败

项目场景 pycharm安装第三方库 问题描述 python 安装第三方库总是安装失败 原因分析&#xff1a; 提示&#xff1a;这里填写问题的分析&#xff1a; 1.网络 2.网墙 解决方案&#xff1a; 加个镜像 –trusted-host mirrors.aliyun.com

JTS: 24 MinimumDiameter 最小矩形

文章目录 版本代码 版本 org.locationtech.jts:jts-core:1.19.0 链接: github 代码 package pers.stu.algorithm;import org.locationtech.jts.algorithm.MinimumDiameter; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import…

移远EC600U-CN开发板 11.15

制作一个简单UI: 1."端口设置"模块 *效果图 *代码 def backEvent(evt): #返回主界面code evt.get_code() if code lv.EVENT.CLICKED:lv.scr_load(mainInterface)def popUpEvent(evt): #弹窗提醒code evt.get_code()if code lv.EVENT.CL…

树和森林 查找

讨论3.1 黄金分割查找&#xff1f; 在二分查找中&#xff0c;我们是取mid等于left和right的中间值&#xff0c;即用等分的方法进行查找. 那为什么一定要等分呐&#xff1f;能不能进行“黄金分割”&#xff1f;也就是midleft0.618(right-left),当然mid要取整数。如果这样查找&…

Vue3中使用provide和inject依赖注入完成父组件和孙子组件之间参数传递

Vue3中使用provide和inject依赖注入完成父组件和孙子组件之间参数传递 官网介绍 注意以下写法都是使用setup 代码结构 依赖注入-父组件 import { ref, provide } from "vue"const outDialogCardInfo ref() function updateOutDialogCardInfo(item) {console.log…

微信这4个功能容易暴露隐私,记得关闭

每天高频使用微信的我们&#xff0c;常常觉得安全无忧&#xff0c;然而这样的想法并不准确。尽管微信本身的安全性能极高&#xff0c;但若我们不主动设置相关功能&#xff0c;个人隐私和位置信息仍可能被暴露。 在微信朋友圈上&#xff0c;有些人喜欢分享生活的点滴&#xff0c…

LLM(四)| Chinese-LLaMA-Alpaca:包含中文 LLaMA 模型和经过指令微调的 Alpaca 大型模型

论文题目&#xff1a;《EFFICIENT AND EFFECTIVE TEXT ENCODING FOR CHINESE LL AMA AND ALPACA》 ​论文地址&#xff1a;https://arxiv.org/pdf/2304.08177v1.pdf Github地址&#xff1a;https://github.com/ymcui/Chinese-LLaMA-Alpaca 一、项目介绍 通过在原有的LLaMA词…

嵌入式LINUX——环境搭建 windows、虚拟机、开发板 互ping

摘要&#xff1a; 本文包含&#xff0c;如何设置linux开发板和虚拟机、windows 互ping成功 以及设置过程中出现的虚拟机、开发板查询不到eth0 windows ping开发板出项丢包等问题的解决方式。 windows端设置 windows端插入USB转网卡 打开windows桌面下右下角的网络标识 打…

UI自动化测试(弹出框,多窗口)

一、弹出框实战 1、在UI自动化测试中经常会遇到Alert弹出框的场景。Alert类是对话框的处理&#xff0c;主要是对alert警告框。confirm确认框&#xff0c;promp消息对话框。 text():获取alert的文本 dismiss ():点击取消 accept():接受 send-keys():输入 from selenium import …

继承、多态

复习 需求&#xff1a; 编写一个抽象类&#xff1a;职员Employee,其中定义showSalary(int s)抽象方法&#xff1b;编写Employee的子类&#xff0c;分别是销售员Sales和经理Manager,分别在子类中实现对父类抽象方法的重写&#xff0c;并编写测试类Test查看输出结果 package cn.…

多媒体播放器Infuse mac中文版软件特点

Infuse mac是一款多媒体播放器应用&#xff0c;它支持播放多种格式的视频文件、音频文件和图片文件&#xff0c;并且可以通过AIrPlay将媒体内容投放到其他设备上。Infuse还支持在线视频流媒体播放和本地网络共享&#xff0c;用户可以通过它来访问家庭网络上的媒体文件。 Infuse…

<C++> 优先级队列

目录 前言 一、priority_queue的使用 1. 成员函数 2. 例题 二、仿函数 三、模拟实现 1. 迭代器区间构造函数 && AdjustDown 2. pop 3. push && AdjustUp 4. top 5. size 6. empty 四、完整实现 总结 前言 优先级队列以及前面的双端队列基本上已经脱离了队列定…

【1】Maxwell3D闭合线圈小实例仿真

//正文开始前的唠唠&#xff1a;首先声明&#xff0c;本人是00后新人小白一枚&#xff0c;本科计算机专业&#xff0c;现目前工作需要用到一些仿真工具&#xff0c;属于是从零开始学习仿真软件&#xff0c;文章内容为本人的学习笔记&#xff08;所以对于小白来说非常友好&#…

折扣零售新浪潮,揭秘品牌如何盘活千家门店

近两年&#xff0c;随着新经济环境的革新&#xff0c;人们流行起了“反向消费”&#xff0c;开始追求高性价的特价好物。于是&#xff0c;顺应人们消费理念和新需求的折扣零售便开始日渐火热&#xff0c;也让更多品牌与资本加入折扣零售赛道。 根据《2023-2028年中国折扣商店行…

vim——“Linux”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;小雅兰的内容是Linux的开发工具——vim。下面&#xff0c;我们一起进入Linux的世界吧&#xff01;&#xff01;&#xff01; Linux编辑器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 vim操…

【力扣题:循环队列】

文章目录 一.题目描述二. 思路解析三. 代码实现 一.题目描述 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好…

cudnn安装

安装地址 cudnn安装地址&#xff1a;https://developer.nvidia.com/rdp/cudnn-download 安装 选择windows版本的下载&#xff0c;我这里选择的这个&#xff1a; 下载之后解压即可。 后续 后续&#xff1a;第一步 把cudnn的bin&#xff0c;include&#xff0c;lib三个文件…

原力CEO赵锐:ToDesk是国内唯一适合高精远程办公需求的解决方案

随着数字办公在各行业的渗透&#xff0c;远程办公也逐渐成为一种常态。2000多名艺术家员工遍布全球各地的江苏原力数字科技股份有限公司&#xff08;下称&#xff1a;原力&#xff09;&#xff0c;是一家国内业务范围、规模均遥遥领先的数字业务内容提供商。一直以来&#xff0…

轻量封装WebGPU渲染系统示例<32>- 若干线框对象(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/WireframeEntityTest.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下: export class WireframeEntityTest {private mRsc…

第四代智能井盖传感器:井盖位移怎么办?

城市的每一个井盖虽然看似平凡&#xff0c;但其在城市运行中发挥着不可或缺的作用。随着科学技术的不断发展&#xff0c;智能井盖传感器的引入为城市管理带来了革命性的变化。在对于传统井盖出现位移等异常现象&#xff0c;智能井盖传感器可以提供更好的解决方法。 井盖位移怎么…