学习源码是netty-all:4.1.52.Finar,阅读此源码,手写一个最简版的Netty,帮助自己理解netty设计思想。 手写实现的Netty源码(包含服务器demo和客户端demo) netty-starter.zip 项目目录结构如下图 netty-starter/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
< project xmlns = " http://maven.apache.org/POM/4.0.0" xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation= " http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" >
< modelVersion> 4.0.0</ modelVersion>
< packaging> pom</ packaging>
< modules>
< module> netty-all</ module>
< module> echo-server</ module>
< module> echo-client</ module>
</ modules>
< parent>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-parent</ artifactId>
< version> 2.3.4.RELEASE</ version>
< relativePath/>
</ parent>
< groupId> io.netty</ groupId>
< artifactId> netty-starter</ artifactId>
< version> 0.0.1-SNAPSHOT</ version>
< name> netty-starter</ name>
< description> Demo project for Spring Boot</ description>
< properties>
< java.version> 1.8</ java.version>
</ properties>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter</ artifactId>
</ dependency>
< dependency>
< groupId> org.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
< optional> true</ optional>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-test</ artifactId>
< scope> test</ scope>
</ dependency>
</ dependencies>
< build>
< plugins>
< plugin>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-maven-plugin</ artifactId>
</ plugin>
</ plugins>
</ build>
</ project>
<?xml version="1.0" encoding="UTF-8"?>
< project xmlns = " http://maven.apache.org/POM/4.0.0"
xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation= " http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
< parent>
< artifactId> netty-starter</ artifactId>
< groupId> io.netty</ groupId>
< version> 0.0.1-SNAPSHOT</ version>
</ parent>
< modelVersion> 4.0.0</ modelVersion>
< artifactId> netty-all</ artifactId>
< properties>
< maven.compiler.source> 16</ maven.compiler.source>
< maven.compiler.target> 16</ maven.compiler.target>
</ properties>
</ project>
package com. zhiguo. netty ;
import com. zhiguo. handler. ServerChannelInitializer ;
import io. netty. bootstrap. ServerBootstrap ;
import io. netty. channel. nio. NioEventLoopGroup ;
import io. netty. channel. socket. nio. NioServerSocketChannel ;
import lombok. Data ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. beans. factory. annotation. Value ;
import org. springframework. boot. CommandLineRunner ;
import org. springframework. stereotype. Component ;
@Slf4j
@Data
@Component
public class NettyServer implements CommandLineRunner {
@Value ( "${netty.port}" )
private int port;
@Autowired
private ServerChannelInitializer serverChannelInitializer;
@Override
public void run ( String . . . args) throws Exception {
NioEventLoopGroup bossGroup = new NioEventLoopGroup ( ) ;
NioEventLoopGroup workerGroup = new NioEventLoopGroup ( ) ;
try {
ServerBootstrap serverBootstrap = new ServerBootstrap ( ) ;
serverBootstrap. group ( bossGroup, workerGroup) ;
serverBootstrap. channel ( NioServerSocketChannel . class ) ;
serverBootstrap. childHandler ( serverChannelInitializer) ;
serverBootstrap. bind ( port) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
package com. zhiguo. netty ;
import com. zhiguo. handler. ClientChannelInitializer ;
import io. netty. bootstrap. Bootstrap ;
import io. netty. channel. EventLoopGroup ;
import io. netty. channel. nio. NioEventLoopGroup ;
import io. netty. channel. socket. nio. NioSocketChannel ;
import lombok. Data ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. beans. factory. annotation. Value ;
import org. springframework. boot. CommandLineRunner ;
import org. springframework. stereotype. Component ;
@Slf4j
@Data
@Component
public class NettyClient implements CommandLineRunner {
@Value ( "${netty.host}" )
private String host;
@Value ( "${netty.port}" )
private int port;
@Autowired
private ClientChannelInitializer clientChannelInitializer;
@Override
public void run ( String . . . args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup ( 1 ) ;
Bootstrap bootstrap = new Bootstrap ( ) ;
bootstrap. group ( group) . channel ( NioSocketChannel . class ) ;
bootstrap. handler ( clientChannelInitializer) ;
bootstrap. connect ( host, port) ;
}
}
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" - XX: TieredStopAtLevel = 1 - noverify - Dspring . output. ansi. enabled= always "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar=56861:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\bin" - Dcom . sun. management. jmxremote - Dspring . jmx. enabled= true - Dspring . liveBeansView. mbeanDomain - Dspring . application. admin. enabled= true - Dfile . encoding= UTF- 8 - classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;D:\gitee\netty-starter\echo-server\target\classes;D:\gitee\netty-starter\netty-all\target\classes;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot-starter\2.3.4.RELEASE\spring-boot-starter-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot\2.3.4.RELEASE\spring-boot-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-context\5.2.9.RELEASE\spring-context-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-aop\5.2.9.RELEASE\spring-aop-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-beans\5.2.9.RELEASE\spring-beans-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-expression\5.2.9.RELEASE\spring-expression-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.4.RELEASE\spring-boot-autoconfigure-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.3.4.RELEASE\spring-boot-starter-logging-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\Admin\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\Admin\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;C:\Users\Admin\.m2\repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;C:\Users\Admin\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\Admin\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-core\5.2.9.RELEASE\spring-core-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-jcl\5.2.9.RELEASE\spring-jcl-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;C:\Users\Admin\.m2\repository\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar;C:\Users\Admin\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar" com. zhiguo. EchoServerApplication
. ____ _ __ _ _
/ \\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | ' _ | '_| | ' _ \/ _` | \ \ \ \
\\/ ___) | | _) | | | | | || ( _| | ) ) ) )
' | ____| . __| _| | _| _| | _\__, | / / / /
== == == == = | _|= == == == == == == = | ___/= / _/ _/ _/
:: Spring Boot :: ( v2. 3.4 . RELEASE)
2021 - 10 - 12 10 : 23 : 14.517 INFO 5412 -- - [ main] com. zhiguo. EchoServerApplication : Starting EchoServerApplication on PS- 12 with PID 5412 ( D : \gitee\netty- starter\echo- server\target\classes started by Admin in D : \gitee\netty- starter)
2021 - 10 - 12 10 : 23 : 14.520 INFO 5412 -- - [ main] com. zhiguo. EchoServerApplication : No active profile set, falling back to default profiles: default
2021 - 10 - 12 10 : 23 : 14.919 INFO 5412 -- - [ main] com. zhiguo. EchoServerApplication : Started EchoServerApplication in 0.735 seconds ( JVM running for 1.402 )
服务端开放端口:0.0 .0 .0 / 0.0 .0 .0 : 8008
EchoServer read:nihao
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" - XX: TieredStopAtLevel = 1 - noverify - Dspring . output. ansi. enabled= always "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar=56976:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\bin" - Dcom . sun. management. jmxremote - Dspring . jmx. enabled= true - Dspring . liveBeansView. mbeanDomain - Dspring . application. admin. enabled= true - Dfile . encoding= UTF- 8 - classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;D:\gitee\netty-starter\echo-client\target\classes;D:\gitee\netty-starter\netty-all\target\classes;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot-starter\2.3.4.RELEASE\spring-boot-starter-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot\2.3.4.RELEASE\spring-boot-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-context\5.2.9.RELEASE\spring-context-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-aop\5.2.9.RELEASE\spring-aop-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-beans\5.2.9.RELEASE\spring-beans-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-expression\5.2.9.RELEASE\spring-expression-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.4.RELEASE\spring-boot-autoconfigure-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.3.4.RELEASE\spring-boot-starter-logging-2.3.4.RELEASE.jar;C:\Users\Admin\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\Admin\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\Admin\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;C:\Users\Admin\.m2\repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;C:\Users\Admin\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\Admin\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-core\5.2.9.RELEASE\spring-core-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\springframework\spring-jcl\5.2.9.RELEASE\spring-jcl-5.2.9.RELEASE.jar;C:\Users\Admin\.m2\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;C:\Users\Admin\.m2\repository\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar;C:\Users\Admin\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar" com. zhiguo. EchoClientApplication
. ____ _ __ _ _
/ \\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | ' _ | '_| | ' _ \/ _` | \ \ \ \
\\/ ___) | | _) | | | | | || ( _| | ) ) ) )
' | ____| . __| _| | _| _| | _\__, | / / / /
== == == == = | _|= == == == == == == = | ___/= / _/ _/ _/
:: Spring Boot :: ( v2. 3.4 . RELEASE)
2021 - 10 - 12 10 : 23 : 23.485 INFO 14240 -- - [ main] com. zhiguo. EchoClientApplication : Starting EchoClientApplication on PS- 12 with PID 14240 ( D : \gitee\netty- starter\echo- client\target\classes started by Admin in D : \gitee\netty- starter)
2021 - 10 - 12 10 : 23 : 23.487 INFO 14240 -- - [ main] com. zhiguo. EchoClientApplication : No active profile set, falling back to default profiles: default
2021 - 10 - 12 10 : 23 : 23.885 INFO 14240 -- - [ main] com. zhiguo. EchoClientApplication : Started EchoClientApplication in 0.736 seconds ( JVM running for 1.413 )
客户端链接远端:127.0 .0 .1 : 8008
EchoClient read:hello