├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── netty-all-4.1.24.Final.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── nettydemo
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── nettydemo
│ │ │ ├── MainActivity.kt
│ │ │ ├── UIScheduler.java
│ │ │ ├── tcp
│ │ │ ├── DemoDecoder.java
│ │ │ ├── DemoEncoder.java
│ │ │ ├── DemoMessage.java
│ │ │ ├── ProtocolUtils.java
│ │ │ ├── Unpack.java
│ │ │ ├── client
│ │ │ │ ├── ConnectionClient.java
│ │ │ │ └── IConnectionListener.java
│ │ │ └── server
│ │ │ │ ├── ConnectionServer.java
│ │ │ │ └── IClientListener.java
│ │ │ └── ui
│ │ │ └── theme
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── nettydemo
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 | .idea
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NettyDemo
2 |
3 | ## TCP Client
4 |
5 | #### 初始化
6 | ```
7 | ConnectionClient.getConnectionClient().init()
8 | ConnectionClient.getConnectionClient().connect()
9 | ```
10 | #### 发送消息
11 |
12 | ```
13 | ConnectionClient.getConnectionClient().writeMessage()
14 | ```
15 |
16 | #### 断开连接
17 | ```
18 | ConnectionClient.getConnectionClient().disConnect()
19 | ```
20 |
21 | ## TCP Server
22 |
23 | #### 启动服务
24 |
25 | ```
26 | ConnectionServer.getEngin().init()
27 | ```
28 |
29 | #### 向某个客户端发送消息
30 |
31 | ```
32 | ConnectionServer.getEngin().writeMessage()
33 | ```
34 |
35 | #### 关闭服务
36 |
37 | ```
38 | ConnectionServer.getEngin().disConnect()
39 | ```
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | }
5 |
6 | android {
7 | namespace 'com.example.nettydemo'
8 | compileSdk 33
9 |
10 | defaultConfig {
11 | applicationId "com.example.nettydemo"
12 | minSdk 24
13 | targetSdk 33
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | vectorDrawables {
19 | useSupportLibrary true
20 | }
21 | }
22 |
23 | buildTypes {
24 | release {
25 | minifyEnabled false
26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
27 | }
28 | }
29 | compileOptions {
30 | sourceCompatibility JavaVersion.VERSION_1_8
31 | targetCompatibility JavaVersion.VERSION_1_8
32 | }
33 | kotlinOptions {
34 | jvmTarget = '1.8'
35 | }
36 | buildFeatures {
37 | compose true
38 | }
39 | composeOptions {
40 | kotlinCompilerExtensionVersion '1.3.2'
41 | }
42 | packagingOptions {
43 | resources {
44 | excludes += '/META-INF/{AL2.0,LGPL2.1}'
45 | }
46 | }
47 | }
48 |
49 | dependencies {
50 |
51 | implementation 'androidx.core:core-ktx:1.8.0'
52 | implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')
53 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
54 | implementation 'androidx.activity:activity-compose:1.5.1'
55 | implementation platform('androidx.compose:compose-bom:2022.10.00')
56 | implementation 'androidx.compose.ui:ui'
57 | implementation 'androidx.compose.ui:ui-graphics'
58 | implementation 'androidx.compose.ui:ui-tooling-preview'
59 | implementation 'androidx.compose.material3:material3'
60 | implementation files('libs/netty-all-4.1.24.Final.jar')
61 | testImplementation 'junit:junit:4.13.2'
62 | androidTestImplementation 'androidx.test.ext:junit:1.1.5'
63 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
64 | androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00')
65 | androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
66 | debugImplementation 'androidx.compose.ui:ui-tooling'
67 | debugImplementation 'androidx.compose.ui:ui-test-manifest'
68 | }
--------------------------------------------------------------------------------
/app/libs/netty-all-4.1.24.Final.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanshanAndroid/NettyDemo/6e16924e39c2e58e225d78a996433e0d2efe78eb/app/libs/netty-all-4.1.24.Final.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/nettydemo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.nettydemo
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.example.nettydemo", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/nettydemo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.nettydemo
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.material3.MaterialTheme
8 | import androidx.compose.material3.Surface
9 | import androidx.compose.material3.Text
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.tooling.preview.Preview
13 | import com.example.nettydemo.ui.theme.NettyDemoTheme
14 |
15 | class MainActivity : ComponentActivity() {
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | setContent {
19 | NettyDemoTheme {
20 | // A surface container using the 'background' color from the theme
21 | Surface(
22 | modifier = Modifier.fillMaxSize(),
23 | color = MaterialTheme.colorScheme.background
24 | ) {
25 | Greeting("Android")
26 | }
27 | }
28 | }
29 | }
30 | }
31 |
32 | @Composable
33 | fun Greeting(name: String, modifier: Modifier = Modifier) {
34 | Text(
35 | text = "Hello $name!",
36 | modifier = modifier
37 | )
38 | }
39 |
40 | @Preview(showBackground = true)
41 | @Composable
42 | fun GreetingPreview() {
43 | NettyDemoTheme {
44 | Greeting("Android")
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/nettydemo/UIScheduler.java:
--------------------------------------------------------------------------------
1 | package com.example.nettydemo;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | public class UIScheduler {
7 |
8 | private UIScheduler() {}
9 |
10 | private static final UIScheduler sUIScheduler = new UIScheduler();
11 |
12 | private final Handler handler = new Handler(Looper.getMainLooper());
13 |
14 | public static UIScheduler getUIScheduler() {
15 | return sUIScheduler;
16 | }
17 |
18 | public void postRunnable(Runnable runnable) {
19 | handler.post(runnable);
20 | }
21 |
22 |
23 | public void postRunnableDelayed(Runnable runnable, long delay) {
24 | handler.postDelayed(runnable, delay);
25 | }
26 |
27 | public void removeRunnable(Runnable runnable) {
28 | handler.removeCallbacks(runnable);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/nettydemo/tcp/DemoDecoder.java:
--------------------------------------------------------------------------------
1 | package com.example.nettydemo.tcp;
2 |
3 | import java.util.List;
4 |
5 | import io.netty.buffer.ByteBuf;
6 | import io.netty.channel.ChannelHandlerContext;
7 | import io.netty.handler.codec.ByteToMessageDecoder;
8 |
9 |
10 | /**
11 | * @author banshan
12 | * Describe: 解码
13 | */
14 | public class DemoDecoder extends ByteToMessageDecoder {
15 |
16 | private volatile static byte[] LENGTH_BYTES = new byte[4];
17 | private static final int MAX_PACK_SIZE = 1024 * 1024 * 64;
18 |
19 | private volatile static int packetSize = 0;
20 | /**
21 | * 在工作线程中回调
22 | */
23 | @Override
24 | protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List