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

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

1.QT使用Socket

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

QT += network

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

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include 
#include 
#include 
#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==="<fromUnicode(datas);
    // 发送数据
    socket->write(utf8Data);
    socket->flush();

}

void MainWindow::displayError(QAbstractSocket::SocketError)
 {
     qDebug() << "displayError error===="<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.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运行截图

QT使用Socket与安卓Socket互发消息_第1张图片

安卓端运行截图

QT使用Socket与安卓Socket互发消息_第2张图片 

你可能感兴趣的:(android,qt,socket)