Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netty #42

Open
wants to merge 99 commits into
base: 2.0-SNAPSHOT
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
18c6f7e
= tweak with alignments
He-Pin Apr 20, 2017
5630a53
+ 添加第1章的注释
He-Pin Apr 21, 2017
840ea3a
+ 添加第2章的注释
He-Pin Apr 21, 2017
bb0bfc8
+ 添加第4章的注释
He-Pin Apr 21, 2017
f2e4a2c
+ 添加第5章的注释
He-Pin Apr 21, 2017
3350560
+ 第6章的中文注释
He-Pin Apr 21, 2017
1caacca
+ 第7章的中文注释
He-Pin Apr 21, 2017
7bee4fb
+ 第8章的中文注释
He-Pin Apr 21, 2017
49f0d65
+ 第9章的中文注释
He-Pin Apr 21, 2017
ba0e5f2
+ 第10章的中文注释
He-Pin Apr 21, 2017
f91b9d1
+ 第11章的中文注释
He-Pin Apr 21, 2017
5592c55
+ 第12章的中文注释
He-Pin Apr 21, 2017
4772fe3
+ 第13章的中文注释
He-Pin Apr 21, 2017
fb29562
添加本书的内容说明
He-Pin Apr 21, 2017
db92e9b
+ 添加封面图
He-Pin Apr 21, 2017
793a3a4
! 更新编译信息
He-Pin Apr 21, 2017
c743b83
= fix url
He-Pin Apr 21, 2017
e5d0fd3
= 修复对分支的描述
He-Pin Apr 21, 2017
bfe5b75
Update README.md
He-Pin Apr 29, 2017
92df3fd
Update README.md
He-Pin Apr 29, 2017
46703ec
Update README.md
He-Pin Apr 29, 2017
8799c26
! pom upgrade to 4.1.10
He-Pin May 3, 2017
266e315
remove 异步社区
He-Pin May 3, 2017
6dcee72
添加勘误
He-Pin May 3, 2017
3e31e1b
更改文案
He-Pin May 3, 2017
9558380
更改文案
He-Pin May 11, 2017
e274870
添加翻译心得文档
He-Pin May 11, 2017
8d75bad
! pom update to 4.1.11
He-Pin May 12, 2017
393320f
add 签售信息
He-Pin May 14, 2017
fb47d5a
remove 签售信息
He-Pin May 17, 2017
76791c4
change to html
He-Pin May 23, 2017
9530933
update to 4.1.12
He-Pin Jul 6, 2017
c0f97ab
update to 4.1.14
Aug 7, 2017
8721e55
update to 4.1.15
Aug 26, 2017
8b01b9e
! pom upgrade to netty 4.1.16
He-Pin Nov 7, 2017
aae4e44
! pom upgrade to netty 4.1.17
He-Pin Dec 1, 2017
a96c8ea
Merge remote-tracking branch 'origin/ChineseVersion' into ChineseVersion
Dec 8, 2017
a2cb685
! pom update to 4.1.18
Dec 8, 2017
6edc8d4
修改了jquery源来自国内的,不用翻墙
Dec 13, 2017
352d9d5
Merge pull request #7 from JaryZhen/ChineseVersion
He-Pin Dec 13, 2017
2a2f747
! pom upgrade to netty 4.1.19
He-Pin Jan 2, 2018
b7a89a1
! pom upgrade to netty 4.1.20
He-Pin Jan 23, 2018
7488de1
! pom upgrade to netty 4.1.21
He-Pin Feb 8, 2018
d2e24a3
Update pom.xml
He-Pin Mar 21, 2018
3031d63
! pom upgrade to netty 4.1.23
He-Pin Apr 8, 2018
cb011c6
fix comment
MottoX Apr 11, 2018
98310fb
Merge pull request #9 from MottoX/ChineseVersion
He-Pin Apr 17, 2018
b9de35f
! pom upgrade to netty 4.1.25
He-Pin May 15, 2018
74eaf3b
Update README.md
He-Pin Jun 13, 2018
3fb84dd
! pom upgrade to netty 4.1.27
Jul 12, 2018
1e77226
! pom upgrade to netty 4.1.29
Sep 14, 2018
60d26f8
! pom upgrade to netty 4.1.32
Dec 2, 2018
4de8d18
Bump maven-failsafe-plugin from 2.18.1 to 2.22.1
dependabot-support Dec 24, 2018
6baece5
Bump maven-clean-plugin from 2.6.1 to 3.1.0
dependabot-support Dec 24, 2018
bf24be6
Bump maven-surefire-plugin from 2.18.1 to 2.22.1
dependabot-support Dec 24, 2018
cbb47ce
[Security] Bump protobuf-java from 2.5.0 to 3.6.1
dependabot-support Dec 24, 2018
606b2d9
Bump junit from 4.11 to 4.12
dependabot-support Dec 24, 2018
d9b2970
Merge pull request #10 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin Dec 24, 2018
befdf86
Merge pull request #11 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin Dec 24, 2018
87869f0
Merge pull request #12 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin Dec 24, 2018
e790112
Merge pull request #13 from ReactivePlatform/dependabot/maven/com.goo…
He-Pin Dec 24, 2018
87c272a
Merge pull request #14 from ReactivePlatform/dependabot/maven/junit-j…
He-Pin Dec 24, 2018
205b701
add travis
Dec 25, 2018
bf99ae3
Bump maven-compiler-plugin from 3.3 to 3.8.0
dependabot-support Dec 25, 2018
71b44b4
Bump exec-maven-plugin from 1.2.1 to 1.6.0
dependabot-support Dec 25, 2018
c42839d
Bump maven-jar-plugin from 2.6 to 3.1.1
dependabot-support Dec 25, 2018
9477e1e
Merge pull request #15 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin Dec 25, 2018
c574086
Merge pull request #17 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin Dec 25, 2018
cc9f193
Merge pull request #16 from ReactivePlatform/dependabot/maven/org.cod…
He-Pin Dec 25, 2018
1312483
Bump netty-all from 4.1.32.Final to 4.1.33.Final
dependabot-support Jan 22, 2019
fd5cddb
Merge pull request #19 from ReactivePlatform/dependabot/maven/io.nett…
He-Pin Feb 3, 2019
d310812
Bump protobuf-java from 3.6.1 to 3.7.1
dependabot-support Apr 3, 2019
a909c4f
Bump maven-surefire-plugin from 2.22.1 to 2.22.2
dependabot-support May 3, 2019
b00f742
Bump maven-failsafe-plugin from 2.22.1 to 2.22.2
dependabot-support May 3, 2019
3b3378e
Bump maven-compiler-plugin from 3.8.0 to 3.8.1
dependabot-support May 3, 2019
9c68cb6
Merge pull request #23 from ReactivePlatform/dependabot/maven/com.goo…
He-Pin May 8, 2019
0969012
Merge pull request #26 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin May 8, 2019
93699fe
Merge pull request #27 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin May 8, 2019
8eb0e0c
Merge pull request #28 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin May 8, 2019
014ef02
Bump maven-jar-plugin from 3.1.1 to 3.1.2
dependabot-support May 13, 2019
d61a4db
Merge pull request #29 from ReactivePlatform/dependabot/maven/org.apa…
He-Pin May 21, 2019
e251890
Bump protobuf-java from 3.7.1 to 3.8.0
dependabot-preview[bot] May 29, 2019
136c730
Merge pull request #31 from ReactivePlatform/dependabot/maven/com.goo…
He-Pin Jun 21, 2019
842cb72
Bump protobuf-java from 3.8.0 to 3.9.0
dependabot-preview[bot] Jul 12, 2019
150c118
Merge pull request #35 from ReactivePlatform/dependabot/maven/com.goo…
He-Pin Jul 13, 2019
d898e26
upgrade to 4.1.42
Oct 29, 2019
fb97320
modify wrong code comments in chapter 5
LyWang1999 Apr 3, 2020
9878cb7
upgrade to 4.1.49
May 3, 2020
9b052e6
Bump netty-all from 4.1.49.Final to 4.1.58.Final
dependabot-preview[bot] Jan 14, 2021
fbded0f
Merge pull request #78 from ReactivePlatform/dependabot/maven/io.nett…
He-Pin Jan 14, 2021
66e3621
Upgrade to GitHub-native Dependabot
dependabot-preview[bot] Apr 28, 2021
a1fc565
Bump protobuf-java from 3.9.0 to 3.17.3
dependabot-preview[bot] Jun 9, 2021
5fda9f8
!pom bump version to 4.1.75
He-Pin Apr 1, 2022
36af7bb
第9章测试代码注释纠错
mwwcdk Aug 27, 2023
e42e8d5
Merge pull request #104 from mwwcdk/ChineseVersion
He-Pin Aug 27, 2023
af9c055
Merge pull request #100 from ReactivePlatform/dependabot/maven/com.go…
He-Pin Aug 27, 2023
6ce9975
Merge pull request #56 from LyWang1999/ChineseVersion
He-Pin Aug 27, 2023
9f8953d
Merge pull request #92 from ReactivePlatform/dependabot/add-v2-config…
He-Pin Aug 27, 2023
fed334c
!pom bump java version to 1.8
He-Pin Dec 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
updates:
- package-ecosystem: maven
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: com.google.protobuf:protobuf-java
versions:
- 3.14.0
- 3.15.0
- 3.15.1
- 3.15.2
- 3.15.3
- 3.15.4
- 3.15.5
- 3.15.6
- 3.15.7
- dependency-name: io.netty:netty-all
versions:
- 4.1.59.Final
- 4.1.60.Final
- 4.1.62.Final
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: java

sudo: false

jdk:
- oraclejdk8

before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/

cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/

script:
# need to override as the default is to test
- mvn test -B
64 changes: 57 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,66 @@
This Repository contains the source-code for all chapters of the book [Netty in Action](http://manning.com/maurer)
by Norman Maurer and Marvin Allen Wolfthal.
# 《Netty 实战》 Netty In Action 中文版

Latest version: https://github.com/normanmaurer/netty-in-action/tree/2.0-SNAPSHOT
>代码清单已经更新到 Netty 4.1.25.final

Enjoy! Feedback and PR's welcome!
[如何评价这本书-知乎](https://www.zhihu.com/question/58838575)

[关于本书-豆瓣](https://book.douban.com/subject/27038538/)

[京东链接(现货发售):《Netty实战》([美]诺曼·毛瑞尔(Norman Maurer),马文·艾伦·沃尔夫泰尔(Marvin Allen Wolfthal)) ](https://union-click.jd.com/jdc?d=oN4CCW&come=appmessage)

[不负好时光《Netty IN ACTION》中文版《Netty实战》翻译手记](http://www.epubit.com.cn/article/1171)

[不负好时光《Netty IN ACTION》中文版《Netty实战》翻译手记(ATA内网)](https://www.atatech.org/articles/79051?flag_data_from=recommend)

![image](https://cloud.githubusercontent.com/assets/501740/25295296/94d2ef06-2715-11e7-9a2a-916d77014cfc.png)


## 内容提要

本书是为想要或者正在使用 Java 从事高性能网络编程的人而写的,循序渐进地介绍了 Netty
各个方面的内容。

本书共分为 4 个部分:第一部分详细地介绍 Netty 的相关概念以及核心组件,第二部分介绍
自定义协议经常用到的编解码器,第三部分介绍 Netty 对于应用层高级协议的支持,会覆盖常见
的协议及其在实践中的应用,第四部分是几个案例研究。此外,附录部分还会简单地介绍 Maven,
以及如何通过使用 Maven 编译和运行本书中的示例。

阅读本书不需要读者精通 Java 网络和并发编程。如果想要更加深入地理解本书背后的理念
以及 Netty 源码本身,可以系统地学习一下 Java 网络编程、 NIO、并发和异步编程以及相关的
设计模式。

## 说明

这个仓库包含了[Netty In Action](http://www.manning.com/maurer/) 这本书的中文版 [Netty实战](http://www.epubit.com.cn) 的代码清单.
为了更好地服务于读者,进行了如下方面的改进.

Prerequisites

JDK 1.7.0u71 or better
相对于英文版本([2.0-SNAPSHOT](https://github.com/ReactivePlatform/netty-in-action-cn/tree/2.0-SNAPSHOT)分支):

1. 更新了行文中的注释
2. 按照中文版本的排版进行了调整
3. 所有的代码清单以及跳转都使用了中文版书籍中的翻译


## 反馈

上游版本的更新,请直接将PR的目标调整为本仓库的`master`分支

中文版本的更新,请将PR的目标调整为本仓库的`ChineseVersion`分支

## 使用

请直接克隆本项目即可,建议对照原文查看代码.

## 勘误
[前言: 2001 => 2011](https://github.com/ReactivePlatform/netty-in-action-cn/issues/2)

-----

Prerequisites

Maven 3.2.3 or better
maven 3.3.9
JDK 8


If you want to build everything at once, from the top directory run
Expand Down
17 changes: 14 additions & 3 deletions chapter1/src/main/java/nia/chapter1/BlockingIoExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,35 @@
/**
* Created by kerr.
*
* Listing 1.1 Blocking I/O example
* 代码清单 1-1 阻塞 I/O 示例
*/
public class BlockingIoExample {

/**
* 代码清单 1-1 阻塞 I/O 示例
* */
public void serve(int portNumber) throws IOException {
//创建一个新的 ServerSocket,用以监听指定端口上的连接请求
ServerSocket serverSocket = new ServerSocket(portNumber);
//对accept()方法的调用将被阻塞,直到一个连接建立
Socket clientSocket = serverSocket.accept();
//这些流对象都派生于该套接字的流对象
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
String request, response;
//处理循环开始
while ((request = in.readLine()) != null) {
if ("Done".equals(request)) {
break;
}
//请求被传递给服务器的处理方法
response = processRequest(request);
//服务器的响应被发送给了客户端
out.println(response);
//继续执行处理循环
}
response = processRequest(request);
out.println(response);
}

private String processRequest(String request){
Expand Down
22 changes: 18 additions & 4 deletions chapter1/src/main/java/nia/chapter1/ConnectExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,51 @@
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

/**
* Created by kerr.
*
* Listing 1.3 Asynchronous connect
* Listing 1.4 Callback in action
* 代码清单 1-3 异步地建立连接
*
* 代码清单 1-4 回调实战
*/
public class ConnectExample {
private static final Channel CHANNEL_FROM_SOMEWHERE = new NioSocketChannel();

public static void connect(Channel channel) {
/**
* 代码清单 1-3 异步地建立连接
*
* 代码清单 1-4 回调实战
* */
public static void connect() {
Channel channel = CHANNEL_FROM_SOMEWHERE; //reference form somewhere
// Does not block
//异步地连接到远程节点
ChannelFuture future = channel.connect(
new InetSocketAddress("192.168.0.1", 25));
//注册一个 ChannelFutureListener,以便在操作完成时获得通知
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
//检查操作的状态
if (future.isSuccess()) {
//如果操作是成功的,则创建一个 ByteBuf 以持有数据
ByteBuf buffer = Unpooled.copiedBuffer(
"Hello", Charset.defaultCharset());
//将数据异步地发送到远程节点。返回一个 ChannelFuture
ChannelFuture wf = future.channel()
.writeAndFlush(buffer);
// ...
} else {
//如果发生错误,则访问描述原因的 Throwable
Throwable cause = future.cause();
cause.printStackTrace();
}
}
});

}
}
3 changes: 2 additions & 1 deletion chapter1/src/main/java/nia/chapter1/ConnectHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
/**
* Created by kerr.
*
* Listing 1.2 ChannelHandler triggered by a callback
* 代码清单 1-2 被回调触发的 ChannelHandler
*/
public class ConnectHandler extends ChannelInboundHandlerAdapter {
@Override
//当一个新的连接已经被建立时,channelActive(ChannelHandlerContext)将会被调用
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
System.out.println(
Expand Down
8 changes: 4 additions & 4 deletions chapter1/src/main/java/nia/chapter1/package-info.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* kerr.
*
* Listing 1.1 Blocking I/O example {@link nia.chapter1.BlockingIoExample#serve(int)}
* 代码清单 1-1 阻塞 I/O 示例 {@link nia.chapter1.BlockingIoExample#serve(int)}
*
* Listing 1.2 ChannelHandler triggered by a callback {@link nia.chapter1.ConnectHandler}
* 代码清单 1-2 被回调触发的 ChannelHandler {@link nia.chapter1.ConnectHandler}
*
* Listing 1.3 Asynchronous connect {@link nia.chapter1.ConnectExample#connect(io.netty.channel.Channel)}
* 代码清单 1-3 异步地建立连接 {@link nia.chapter1.ConnectExample#connect()}
*
* Listing 1.4 Callback in action {@link nia.chapter1.ConnectExample#connect(io.netty.channel.Channel)}
* 代码清单 1-4 回调实战 {@link nia.chapter1.ConnectExample#connect()}
*/
package nia.chapter1;
4 changes: 3 additions & 1 deletion chapter10/src/main/java/nia/chapter10/ByteToCharDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
import java.util.List;

/**
* Listing 10.8 Class ByteToCharDecoder
* 代码清单 10-8 ByteToCharDecoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了ByteToMessageDecoder
public class ByteToCharDecoder extends ByteToMessageDecoder {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in,
List<Object> out) throws Exception {
if (in.readableBytes() >= 2) {
//将一个或者多个 Character 对象添加到传出的 List 中
out.add(in.readChar());
}
}
Expand Down
8 changes: 5 additions & 3 deletions chapter10/src/main/java/nia/chapter10/CharToByteEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
import io.netty.handler.codec.MessageToByteEncoder;

/**
* Listing 10.9 Class CharToByteEncoder
* 代码清单 9 CharToByteEncoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
public class CharToByteEncoder
extends MessageToByteEncoder<Character> {
//扩展了MessageToByteEncoder
public class CharToByteEncoder extends
MessageToByteEncoder<Character> {
@Override
public void encode(ChannelHandlerContext ctx, Character msg,
ByteBuf out) throws Exception {
//将 Character 解码为 char,并将其写入到出站 ByteBuf 中
out.writeChar(msg);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import io.netty.channel.CombinedChannelDuplexHandler;

/**
* Listing 10.10 CombinedChannelDuplexHandler<I,O>
* 代码清单 CombinedChannelDuplexHandler<I,O>
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/

//通过该解码器和编码器实现参数化 CombinedByteCharCodec
public class CombinedByteCharCodec extends
CombinedChannelDuplexHandler<ByteToCharDecoder, CharToByteEncoder> {
public CombinedByteCharCodec() {
//将委托实例传递给父类
super(new ByteToCharDecoder(), new CharToByteEncoder());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
import java.util.List;

/**
* Listing 10.3 Class IntegerToStringDecoder
* 代码清单 10-3 IntegerToStringDecoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
public class IntegerToStringDecoder
extends MessageToMessageDecoder<Integer> {
//扩展了MessageToMessageDecoder<Integer>
public class IntegerToStringDecoder extends
MessageToMessageDecoder<Integer> {
@Override
public void decode(ChannelHandlerContext ctx, Integer msg,
List<Object> out) throws Exception {
//将 Integer 消息转换为它的 String 表示,并将其添加到输出的 List 中
out.add(String.valueOf(msg));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
import java.util.List;

/**
* Listing 10.6 Class IntegerToStringEncoder
* 代码清单 10-6 IntegerToStringEncoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了 MessageToMessageEncoder
public class IntegerToStringEncoder
extends MessageToMessageEncoder<Integer> {

@Override
public void encode(ChannelHandlerContext ctx, Integer msg,
List<Object> out) throws Exception {
//将 Integer 转换为 String,并将其添加到 List 中
out.add(String.valueOf(msg));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@
import java.util.List;

/**
* Listing 10.4 TooLongFrameException
* 代码清单 10-4 TooLongFrameException
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/

//扩展 ByteToMessageDecoder 以将字节解码为消息
public class SafeByteToMessageDecoder extends ByteToMessageDecoder {
private static final int MAX_FRAME_SIZE = 1024;

@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in,
List<Object> out) throws Exception {
int readable = in.readableBytes();
//检查缓冲区中是否有超过 MAX_FRAME_SIZE 个字节
if (readable > MAX_FRAME_SIZE) {
//跳过所有的可读字节,抛出 TooLongFrameException 并通知 ChannelHandler
in.skipBytes(readable);
throw new TooLongFrameException("Frame too big!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
import io.netty.handler.codec.MessageToByteEncoder;

/**
* Listing 10.5 Class ShortToByteEncoder
* 代码清单 10-5 ShortToByteEncoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了MessageToByteEncoder
public class ShortToByteEncoder extends MessageToByteEncoder<Short> {
@Override
public void encode(ChannelHandlerContext ctx, Short msg, ByteBuf out)
throws Exception {
//将 Short 写入 ByteBuf 中
out.writeShort(msg);
}
}
Loading