背景:安卓设备通过usb网络共享给Linux,此时安卓设备与linux处于同一网络环境,符合使用socket的条件,linux做客户端,安卓做服务端
QT += network
- #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
- #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代码就写完了,接下来我们看一下安卓端的发送与接收:
- 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运行截图
安卓端运行截图