当前位置: 首页 > news >正文

安卓 tcp 客户端

安卓 tcp 客户端

Server:8888 是Qt 写的Tcp 服务器 ip 是 192.168.2.103 port是8888
安卓手机运行 kotlin 语法的Tcp Client ,连接,收发数据
效果如下图

在这里插入图片描述

Tcpclient

package com.example.myapplicationimport android.os.Handler
import android.os.Looper
import android.util.Log
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.net.Socketclass TcpClient(private val ipAddress: String, private val port: Int) {private lateinit var socket: Socketprivate lateinit var reader: BufferedReaderprivate lateinit var writer: BufferedWriter// 接收线程private val messageReceiverThread = Thread {//主消息处理器,用于向外部发送tcp收到的数据val handler = Handler(Looper.getMainLooper())val buffer = StringBuilder()val charBuffer = CharArray(1024) // 调整缓冲区大小while (!Thread.currentThread().isInterrupted) {try {
//                val receivedData = reader.readLine() ?: ""
//                Log.d("TcpClient",receivedData)
//                handler.post {
//                    onDataReceived(receivedData)
//                }val bytesRead = reader.read(charBuffer)if (bytesRead == -1) {// 如果没有更多数据可读,则退出循环Log.d("TcpClient","continue")continue}// 清空缓冲区buffer.clear()// 将读取的数据追加到缓冲区buffer.append(charBuffer, 0, bytesRead)// 通知UI线程更新UIhandler.post {Log.d("TcpClient","buffer : "+buffer.toString())onDataReceived(buffer.toString())}} catch (e: Exception) {Log.e("TcpClient","Exception")e.printStackTrace()break}}}// 外部调用,定义数据接收监听器接口interface DataReceivedListener {fun onDataReceived(data: String)}private var dataReceivedListener: DataReceivedListener? = null// 外部调用,设置数据接收监听器fun setDataReceivedListener(listener: DataReceivedListener) {dataReceivedListener = listener}// 通知数据接收事件private fun onDataReceived(data: String) {dataReceivedListener?.onDataReceived(data)}// 1fun connectToServer() {try {socket = Socket(ipAddress, port)reader = BufferedReader(InputStreamReader(socket.getInputStream()))writer = BufferedWriter(OutputStreamWriter(socket.getOutputStream()))} catch (e: Exception) {e.printStackTrace()}}fun sendMessage(message: String) {try {writer.write(message)
//            writer.newLine()writer.flush()} catch (e: Exception) {e.printStackTrace()}}// 2fun startMessageReceiver() {messageReceiverThread.start()}fun stopMessageReceiver() {messageReceiverThread.interrupt()}fun close() {try {socket.close()} catch (e: Exception) {e.printStackTrace()}}
}

MainActivity

package com.example.myapplicationimport android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.TextViewclass MainActivity : AppCompatActivity() {private lateinit var ipAddress: Stringprivate var port: Int = 0private lateinit var recvText: EditTextprivate lateinit var tcpClient: TcpClientoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)recvText = findViewById(R.id.recvText)// start tcpval startButton: Button = findViewById(R.id.startBtn)// 设置按钮点击事件startButton.setOnClickListener {// 设置IP地址和端口(请根据需要修改)ipAddress = findViewById<EditText?>(R.id.ipText).text.toString()port = findViewById<EditText?>(R.id.portNum).text.toString().toInt()// 创建TcpClient实例tcpClient = TcpClient(ipAddress, port)// 设置数据接收监听器tcpClient.setDataReceivedListener(object : TcpClient.DataReceivedListener {override fun onDataReceived(data: String) {// 在数据接收回调中更新UIupdateUI(data)}})// 在新线程中执行连接操作Thread {tcpClient.connectToServer()tcpClient.startMessageReceiver()}.start()}// stop tcpval stopBtn: Button = findViewById(R.id.stopBtn)stopBtn.setOnClickListener {Thread {tcpClient.stopMessageReceiver()tcpClient.close()}.start()}// send on threadval sendBtn: Button = findViewById(R.id.sendBtn)sendBtn.setOnClickListener {Thread {var sendText : EditText= findViewById(R.id.sendText)tcpClient.sendMessage(sendText.text.toString())}.start()}var cleanBtn:Button = findViewById(R.id.cleanBtn)cleanBtn.setOnClickListener {recvText.text.clear()}}private fun updateUI(data: String) {Log.d("MainActivity","data:"+data)val editableText = Editable.Factory.getInstance().newEditable(data)recvText.text?.append(editableText)}}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/linearLayout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="406dp"android:layout_height="53dp"android:orientation="horizontal"><EditTextandroid:id="@+id/ipText"android:layout_width="204dp"android:layout_height="47dp"android:layout_weight="4"android:ems="10"android:inputType="text"android:text="192.168.2.103" /><EditTextandroid:id="@+id/portNum"android:layout_width="204dp"android:layout_height="45dp"android:layout_weight="1"android:ems="10"android:inputType="number"android:text="8888" /></LinearLayout><LinearLayoutandroid:layout_width="409dp"android:layout_height="55dp"android:orientation="horizontal"><Buttonandroid:id="@+id/startBtn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="start" /><Buttonandroid:id="@+id/stopBtn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="stop" /><Spaceandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1" /></LinearLayout><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="send data"android:textSize="20sp" /><EditTextandroid:id="@+id/sendText"android:layout_width="match_parent"android:layout_height="148dp"android:layout_weight="4"android:ems="10"android:gravity="start|top"android:inputType="textMultiLine" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/sendBtn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="send" /><Buttonandroid:id="@+id/cleanBtn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="clean recv" /></LinearLayout><TextViewandroid:id="@+id/textView3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="recv data"android:textSize="20sp" /><EditTextandroid:id="@+id/recvText"android:layout_width="match_parent"android:layout_height="202dp"android:layout_weight="4"android:ems="10"android:gravity="start|top"android:inputType="textMultiLine" /></LinearLayout>

AndroidManifest.xml 配置清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myapplication"><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activityandroid:name=".MainActivity"android:exported="false"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

build.gradle (app)

plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}android {compileSdkVersion 30buildToolsVersion "30.0.3"defaultConfig {applicationId "com.example.myapplication"minSdkVersion 28targetSdkVersion 30versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.2.1'implementation 'androidx.constraintlayout:constraintlayout:2.0.1'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

build.gradle (my proj )

使用国内镜像

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {repositories {maven { url 'https://maven.aliyun.com/repository/google' }maven { url 'https://maven.aliyun.com/repository/jcenter' }maven { url 'https://maven.aliyun.com/repository/public' }maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
//        google()
//        mavenCentral()}dependencies {classpath "com.android.tools.build:gradle:4.2.1"classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0'// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}allprojects {repositories {maven { url 'https://maven.aliyun.com/repository/google' }maven { url 'https://maven.aliyun.com/repository/jcenter' }maven { url 'https://maven.aliyun.com/repository/public' }maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
//        google()
//        mavenCentral()
//        jcenter() // Warning: this repository is going to shut down soon}
}task clean(type: Delete) {delete rootProject.buildDir
}

相关文章:

安卓 tcp 客户端

安卓 tcp 客户端 Server:8888 是Qt 写的Tcp 服务器 ip 是 192.168.2.103 port是8888 安卓手机运行 kotlin 语法的Tcp Client &#xff0c;连接&#xff0c;收发数据 效果如下图 Tcpclient package com.example.myapplicationimport android.os.Handler import android.os.Loo…...

flutter plugins插件【三】【Flutter Intl】

3、 Flutter Intl 多语言国际化 在Android Studio中菜单Tools找到flutter intl创建多语言配置。 创建后会在pubspec.yaml出现 flutter_intl:enabled: true 在工程的lib会生成l10n与generated文件夹 l10n包含 intl_en.arb intl_zn.arb 我们在intl_en.arb添加 { home: &quo…...

简单了解ICMP协议

目录 一、什么是ICMP协议&#xff1f; 二、ICMP如何工作&#xff1f; 三、ICMP报文格式 四、ICMP的作用 五、ICMP的典型应用 5.1 Ping程序 5.2 Tracert(Traceroute)路径追踪程序 一、什么是ICMP协议&#xff1f; ICMP因特网控制报文协议是一个差错报告机制&#xff0c;…...

MVCC究竟是什么?

&#xff11;.MVCC概念 MVCC&#xff0c;全称多版本并发控制 MVCC究竟是什么&#xff1f; 通俗的来说MVCC就是为了在读取数据时不加锁来提高读取效率的一种办法&#xff0c;MVCC解决的是读写时线程安全问题&#xff0c;线程不用去抢占读写锁。MVCC中的读就是快照读&#xff0c…...

Kafka知识点总结

常见名词 生产者和消费者 同一个消费组下的消费者订阅同一个topic时&#xff0c;只能有一个消费者收到消息 要想让订阅同一个topic的消费者都能收到信息&#xff0c;需将它们放到不同的组中 分区机制 启动方法 生成者和消费者监听客户端...

K8s最基本概念

1.K8s概述和特性 k8s是谷歌在2014年开业的容器化集群管理系统 使用K8s进行容器化应用部署 使用K8s利用应用扩展 k8s目标实施让部署容器化应用更加简洁高效-------集群管理系统 1.1 K8s特性 1) 自动装箱&#xff1a;基于容器对应用运行环境的资源配置 2&#xff09;自…...

vulnhub渗透测试靶场练习2

靶场介绍 靶场名&#xff1a;easy_cloudantivirus 靶场地址&#xff1a;https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453 环境搭建 依旧使用VM VirtualBox搭建靶场&#xff0c;攻击机使用的是VMware中的kali&#xff0c;需要将VMware虚拟机kali和virtualbox靶机…...

在R中安装TensorFlow、TensorFlow_Probability、numpy(R与Python系列第二篇)

目录 前言&#xff1a; 1-安装tensorflow库 Step1: 下载R包tensorflow Step2&#xff1a;安装TensorFlow库 Step3&#xff1a;导入R中 2-安装tensorflow_probability库 Step1&#xff1a;下载R包&#xff1a;tfprobability Step2&#xff1a;安装TensorFlow Probability …...

十大管理——项目成本管理

目录 1.成本管理概念 2.成本管理的四个过程域 2.1四个过程的整体理解 ​2.2四个过程的ITO口诀版记忆 2.3过程1——制定项目管理计划 ​2.4过程2——项目成本估算​ 2.5过程3——项目成本预算 2.5过程4——项目成本控制 3计算题 1.成本管理概念 项目成本管理就是要确保…...

Java BIO、NIO、AIO学习总结

前言&#xff1a;关于BIO/NIO/AIO的文章已经汗牛充栋&#xff0c;俺最近比较闲试图系统学习一下&#xff0c;希望大侠多多指教&#xff01; 先来个例子理解一下概念&#xff0c;以银行取款为例&#xff1a; 同步 &#xff1a; 自己亲自出马持银行卡到银行取钱&#xff08;使用…...

sql各种注入案例

目录 1.报错注入七大常用函数 1)ST_LatFromGeoHash (mysql>5.7.x) 2)ST_LongFromGeoHash &#xff08;mysql>5.7.x&#xff09; 3)GTID (MySQL > 5.6.X - 显错<200) 3.1 GTID 3.2 函数详解 3.3 注入过程( payload ) 4)ST_Pointfromgeohash (mysql>5.…...

系统学习Linux-ELK日志收集系统

ELK日志收集系统集群实验 实验环境 角色主机名IP接口httpd192.168.31.50ens33node1192.168.31.51ens33noed2192.168.31.53ens33 环境配置 设置各个主机的ip地址为拓扑中的静态ip&#xff0c;并修改主机名 #httpd [rootlocalhost ~]# hostnamectl set-hostname httpd [root…...

IDEA2023隐藏.idea和.iml文件

IDEA2023隐藏.idea和.iml文件 1. 打开file -> setting,快捷键CtrlAlts2. Editor -> File types3. 点击右侧Ignore files and folders一栏4. 添加需要忽略的文件5. 最重要一步 IDEA新建项目会自动生成一个.idea文件夹和.iml文件&#xff0c;开发中不需要对这两个文件修改&…...

【深入浅出C#】章节 9: C#高级主题:反射和动态编程

反射和动态编程是C#和其他现代编程语言中重要的高级主题&#xff0c;它们具有以下重要性&#xff1a; 灵活性和扩展性&#xff1a;反射允许程序在运行时动态地获取和操作类型信息、成员和对象实例&#xff0c;这使得程序更加灵活和具有扩展性。动态编程则使得程序能够根据运行…...

Gorm简单了解

GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly. 04_GORM查询操作_哔哩哔哩_bilibili 前置&#xff1a; db调用操作语句中间加debug&#xff08;&#xff09;可以显示对应的sql语句 1.Gorm模型定义&#xff08;理解重点&#xff…...

第一百三十三回 StreamProvier

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了通道相关的内容&#xff0c;本章回中将介绍 StreamProvider组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 在Flutter中Stream是经常使用的组件&#xff0c;对该组件的监听可以StremBuilder&#x…...

java 多个list取交集

java 多个list集合根据某个字段取出交集 模拟多个list集合&#xff0c;如下图 如果只有一个集合那么交集就是当前集合&#xff0c;如果有多个集合&#xff0c;那么第一个集合当做目标集合&#xff0c;在通过目标集合去和剩下的集合比较&#xff0c;取出相同的值&#xff0c;运…...

文件上传与下载

文章目录 1. 前端要求2. 后端要求 1. 前端要求 //采用post方法提交文件 method"post" //采用enctype属性 enctype"" //type属性要求 type"file"2. 后端要求 package com.itheima.reggie.controller;import com.itheima.reggie.common.R; impo…...

SpringBoot 整合 RabbitMQ

1. 创建 SpringBoot 工程 把版本改为 2.7.14 引入这两个依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springfr…...

气象科普丨气象站的分类与应用

气象站是一种用于收集、分析和处理气象数据的设备。根据不同的应用场景和监测需求&#xff0c;气象站可以分为以下几类&#xff1a; 一、农业气象站 农业气象站是专门为农业生产服务的气象站&#xff0c;主要监测土壤温度、土壤湿度等参数&#xff0c;为农业生产提供科学依据…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...