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


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

    1.QT使用Socket

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

    QT += network

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

    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3. #include
    4. #include
    5. #include
    6. #include "QTimer"
    7. namespace Ui {
    8. class MainWindow;
    9. }
    10. class MainWindow : public QMainWindow
    11. {
    12. Q_OBJECT
    13. public:
    14. explicit MainWindow(QWidget *parent = nullptr);
    15. ~MainWindow();
    16. public slots:
    17. //用做读取服务端发送的数据
    18. void readData();
    19. //获取当前socket的连接状态
    20. void displayError(QAbstractSocket::SocketError);
    21. private:
    22. Ui::MainWindow *ui;
    23. QTcpSocket *socket;
    24. };
    25. #endif // MAINWINDOW_H

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

    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include "QFile"
    4. #include "QTextCodec"
    5. #include "QDebug"
    6. #include "QFontDatabase"
    7. MainWindow::MainWindow(QWidget *parent) :
    8. QMainWindow(parent),
    9. ui(new Ui::MainWindow)
    10. {
    11. ui->setupUi(this);
    12. socket = new QTcpSocket(this);
    13. socket->abort();
    14. //这个地方是重点,因为安卓端我没有设置ip,那么这里的ip就是USB共享所分配的ip,可以进入安卓端使用ifconfig获取到ip地址
    15. //端口9999是我在安卓服务端设置的,等会安卓端代码会有写
    16. socket->connectToHost("192.168.XXX",9999);
    17. connect(socket, &QTcpSocket::readyRead, this, &MainWindow::readData);
    18. connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
    19. this, SLOT(displayError(QAbstractSocket::SocketError)));
    20. }
    21. void MainWindow::readData() {
    22. qDebug() << "******************************clein====********************************";
    23. QString data = socket->readAll();
    24. QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    25. QString strData = codec->toUnicode(data.toUtf8());
    26. qDebug() << "readData message==="<<strData; // 输出 "11111"
    27. qDebug() << "******************************clein********************************\n";
    28. /*******************************读取到数据以后自动发送数据给服务端**********************************/
    29. // 用于暂存要发送的数据
    30. QString datas = "on_pushButton_2_clicked"; // 要发送的数据
    31. // 将数据转换为 UTF-8 编码
    32. QTextCodec* codecs = QTextCodec::codecForName("UTF-8");
    33. QByteArray utf8Data = codecs->fromUnicode(datas);
    34. // 发送数据
    35. socket->write(utf8Data);
    36. socket->flush();
    37. }
    38. void MainWindow::displayError(QAbstractSocket::SocketError)
    39. {
    40. qDebug() << "displayError error===="<<socket->errorString();
    41. }
    42. MainWindow::~MainWindow()
    43. {
    44. delete ui;
    45. }

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

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

    1. package com.jk.rtk
    2. import android.content.Context
    3. import android.net.ConnectivityManager
    4. import android.net.wifi.WifiManager
    5. import android.os.Build
    6. import android.util.Log
    7. import java.io.IOException
    8. import java.io.InputStream
    9. import java.io.OutputStreamWriter
    10. import java.net.*
    11. import java.util.*
    12. object SocketServer {
    13. private val TAG = SocketServer::class.java.simpleName
    14. var SOCKET_PORT = 9999
    15. private var socket: Socket? = null
    16. private var serverSocket: ServerSocket? = null
    17. private lateinit var mCallback: ServerCallback
    18. var result = true
    19. /**
    20. * 开启服务
    21. */
    22. fun startServer(callback: ServerCallback): Boolean {
    23. Log.i(TAG, "startServer: ")
    24. mCallback = callback
    25. Thread {
    26. try {
    27. serverSocket = ServerSocket(SOCKET_PORT)
    28. while (result) {
    29. socket = serverSocket?.accept()
    30. mCallback.otherMsg("${socket?.inetAddress} to connected")
    31. ServerThread(socket!!, mCallback).start()
    32. }
    33. } catch (e: IOException) {
    34. e.printStackTrace()
    35. result = false
    36. }
    37. }.start()
    38. return result
    39. }
    40. /**
    41. * 关闭服务
    42. */
    43. fun stopServer() {
    44. Log.i(TAG, "stopServer: ")
    45. socket?.apply {
    46. //shutdownInput()
    47. //shutdownOutput()
    48. close()
    49. }
    50. serverSocket?.close()
    51. }
    52. /**
    53. * 发送到客户端
    54. */
    55. fun sendToClient(msg: String) {
    56. Thread {
    57. if (socket!!.isClosed) {
    58. Log.e(TAG, "sendToClient: Socket is closed")
    59. return@Thread
    60. }
    61. Log.e(TAG, "sendToClient: msg====$msg")
    62. try {
    63. val out = OutputStreamWriter(socket!!.getOutputStream(), "UTF-8")
    64. out.write(msg)
    65. out.flush()
    66. mCallback.otherMsg("toClient: $msg")
    67. Log.d(TAG, "发送到客户端成功")
    68. } catch (e: IOException) {
    69. e.printStackTrace()
    70. Log.e(TAG, "向客户端发送消息失败")
    71. }
    72. }.start()
    73. }
    74. /*
    75. * 获取USB共享的ip地址
    76. * */
    77. fun getUsbTetheringIpAddress(): String? {
    78. try {
    79. val interfaces: Enumeration = NetworkInterface.getNetworkInterfaces()
    80. while (interfaces.hasMoreElements()) {
    81. val intf: NetworkInterface = interfaces.nextElement()
    82. val addresses = intf.interfaceAddresses
    83. for (addr in addresses) {
    84. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    85. if (addr.networkPrefixLength >= 16 && !addr.address.isLinkLocalAddress) {
    86. return addr.address.hostAddress
    87. }
    88. } else {
    89. if (addr.address.isSiteLocalAddress && !addr.address.isLinkLocalAddress) {
    90. return addr.address.hostAddress
    91. }
    92. }
    93. }
    94. }
    95. } catch (e: Exception) {
    96. e.printStackTrace()
    97. }
    98. return null
    99. }
    100. class ServerThread(private val socket: Socket, private val callback: ServerCallback) :
    101. Thread() {
    102. override fun run() {
    103. val inputStream: InputStream?
    104. try {
    105. inputStream = socket.getInputStream()
    106. val buffer = ByteArray(1024)
    107. var len: Int
    108. var receiveStr = ""
    109. if (inputStream.available() == 0) {
    110. Log.e(TAG, "inputStream.available() == 0")
    111. }
    112. while (inputStream.read(buffer).also { len = it } != -1) {
    113. receiveStr += String(buffer, 0, len, Charsets.UTF_8).trim()
    114. if (len < 1024) {
    115. Log.e(TAG, "inputStream.receiveStr == $receiveStr")
    116. callback.receiveClientMsg(true, receiveStr)
    117. receiveStr = ""
    118. }
    119. }
    120. } catch (e: IOException) {
    121. e.printStackTrace()
    122. e.message?.let { Log.e("socket error", it) }
    123. callback.receiveClientMsg(false, "")
    124. }
    125. }
    126. }
    127. }

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

    1. (1).先启动服务 与回调函数
    2. boolean isSocket = SocketServer.INSTANCE.startServer(new ServerCallback() {
    3. @Override
    4. public void receiveClientMsg(boolean success, @NonNull String msg) {
    5. Log.e("TAG", "SocketServer receiveClientMsg success=" + success + " msg=" + msg);
    6. }
    7. @Override
    8. public void otherMsg(@NonNull String msg) {
    9. Log.e("TAG", "SocketServer otherMsg msg=" + msg);
    10. }
    11. });
    12. (2).发送数据: SocketServer.INSTANCE.sendToClient("json");

     linux运行截图

    安卓端运行截图

     

  • 相关阅读:
    java计算机毕业设计摄影网上预约管理系统(附源码、数据库)
    【华为机试真题详解】数大雁【2022 Q2 | 100分】
    今年双十二值得买的数码好物推荐!双十二数码产品抢购攻略
    精通Java事务编程-深入理解事务
    spring @value 注入static 注入静态变量方法
    化学制品制造业数智化供应链管理系统:打造智慧供应体系,赋能企业产效提升
    Tomcat多实例与负载均衡
    DOM——事件语法
    Linux常见命令手册
    算法题:分别用c++/python/java实现回文数
  • 原文地址:https://blog.csdn.net/qq_36333309/article/details/134425069