Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Netty 5Óû§Ö¸ÄÏ
 
ÒëÕߣº¹â»ÔÓÂÊ¿ À´Ô´£ºNetty project ·¢²¼ÓÚ 2015-5-28
  4105  次浏览      27
 

ǰÑÔ

ÎÊÌâ

ÏÖÈç½ñÎÒÃÇʹÓÃͨÓõÄÓ¦ÓóÌÐò»òÕßÀà¿âÀ´ÊµÏÖϵͳ֮¼äµØ»¥Ïà·ÃÎÊ£¬±ÈÈçÎÒÃǾ­³£Ê¹ÓÃÒ»¸öHTTP¿Í»§¶ËÀ´´Óweb·þÎñÆ÷ÉÏ»ñÈ¡ÐÅÏ¢£¬»òÕßͨ¹ýweb serviceÀ´Ö´ÐÐÒ»¸öÔ¶³ÌµÄµ÷Óá£

È»¶ø£¬ÓÐʱºòÒ»¸öͨÓõÄЭÒéºÍËûµÄʵÏÖ²¢Ã»Óи²¸ÇһЩ³¡¾°¡£±ÈÈçÎÒÃÇÎÞ·¨Ê¹ÓÃÒ»¸öͨÓõÄHTTP·þÎñÆ÷À´´¦Àí´óÎļþ¡¢µç×ÓÓʼþ¡¢½üʵʱÏûÏ¢±ÈÈç²ÆÎñÐÅÏ¢ºÍ¶àÈËÓÎÏ·Êý¾Ý¡£ÎÒÃÇÐèÒªÒ»¸öºÏÊʵÄЭÒéÀ´´¦ÀíÒ»Ð©ÌØÊâµÄ³¡¾°¡£ÀýÈçÄã¿ÉÒÔʵÏÖÒ»¸öÓÅ»¯µÄAjaxµÄÁÄÌìÓ¦Óá¢Ã½ÌåÁ÷´«Êä»òÕßÊÇ´óÎļþ´«ÊäµÄHTTP·þÎñÆ÷£¬ÄãÉõÖÁ¿ÉÒÔ×Ô¼ºÉè¼ÆºÍʵÏÖÒ»¸öеÄЭÒéÀ´×¼È·µØÊµÏÖÄãµÄÐèÇó¡£

ÁíÍâ²»¿É±ÜÃâµÄÊÂÇéÊÇÄã²»µÃ²»´¦ÀíÕâЩ˽ÓÐЭÒéÀ´È·±£ºÍÔ­ÓÐϵͳµÄ»¥Í¨¡£Õâ¸öÀý×Ó½«»áչʾÈçºÎ¿ìËÙʵÏÖÒ»¸ö²»Ó°ÏìÓ¦ÓóÌÐòÎȶ¨ÐÔºÍÐÔÄܵÄЭÒé¡£

½â¾ö·½°¸

NettyÊÇÒ»¸öÌṩÒ첽ʼþÇý¶¯µÄÍøÂçÓ¦Óÿò¼Ü£¬ÓÃÒÔ¿ìËÙ¿ª·¢¸ßÐÔÄÜ¡¢¸ß¿É¿¿ÐÔµÄÍøÂç·þÎñÆ÷ºÍ¿Í»§¶Ë³ÌÐò¡£

»»¾ä»°Ëµ£¬NettyÊÇÒ»¸öNIO¿ò¼Ü£¬Ê¹ÓÃËü¿ÉÒÔ¼òµ¥¿ìËٵؿª·¢ÍøÂçÓ¦ÓóÌÐò£¬±ÈÈç¿Í»§¶ËºÍ·þÎñ¶ËµÄЭÒé¡£Netty´ó´ó¼ò»¯ÁËÍøÂç³ÌÐòµÄ¿ª·¢¹ý³Ì±ÈÈçTCPºÍUDPµÄ SocketµÄ¿ª·¢¡£

¡°¿ìËٺͼòµ¥¡±²¢²»Òâζ×ÅÓ¦ÓóÌÐò»áÓÐÄÑά»¤ºÍÐÔÄܵ͵ÄÎÊÌ⣬NettyÊÇÒ»¸ö¾«ÐÄÉè¼ÆµÄ¿ò¼Ü£¬Ëü´ÓÐí¶àЭÒéµÄʵÏÖÖÐÎüÊÕÁ˺ܶàµÄ¾­Ñé±ÈÈçFTP¡¢SMTP¡¢HTTP¡¢Ðí¶à¶þ½øÖƺͻùÓÚÎı¾µÄ´«Í³Ð­Ò飬NettyÔÚ²»½µµÍ¿ª·¢Ð§ÂÊ¡¢ÐÔÄÜ¡¢Îȶ¨ÐÔ¡¢Áé»îÐÔÇé¿öÏ£¬³É¹¦µØÕÒµ½Á˽â¾ö·½°¸¡£

ÓÐһЩÓû§¿ÉÄÜÒѾ­·¢ÏÖÆäËûµÄÒ»Ð©ÍøÂç¿ò¼ÜÒ²Éù³Æ×Ô¼ºÓÐͬÑùµÄÓÅÊÆ£¬ËùÒÔÄã¿ÉÄÜ»áÎÊÊÇNettyºÍËüÃǵIJ»Í¬Ö®´¦¡£´ð°¸¾ÍÊÇNettyµÄÕÜѧÉè¼ÆÀíÄî¡£Netty´ÓµÚÒ»Ì쿪ʼ¾ÍΪÓû§ÌṩÁËÓû§ÌåÑé×îºÃµÄAPIÒÔ¼°ÊµÏÖÉè¼Æ¡£ÕýÊÇÒòΪNettyµÄÉè¼ÆÀíÄ²ÅÈÃÎÒÃǵÃÒÔÇáËɵØÔĶÁ±¾Ö¸Äϲ¢Ê¹ÓÃNetty¡£

ÈëÃÅÖ¸ÄÏ

Õâ¸öÕ½ڻá½éÉÜNettyºËÐĵĽṹ£¬²¢Í¨¹ýһЩ¼òµ¥µÄÀý×ÓÀ´°ïÖúÄã¿ìËÙÈëÃÅ¡£µ±Äã¶ÁÍê±¾Õ½ÚÄãÂíÉϾͿÉÒÔÓÃNettyд³öÒ»¸ö¿Í»§¶ËºÍ·þÎñ¶Ë¡£

Èç¹ûÄãÔÚѧϰµÄʱºòϲ»¶¡°×Ô¶¥ÏòÏ£¨top-down£©¡±µÄ·½·¨£¬ÄÇÄã¿ÉÄÜÐèÒªÒª´ÓµÚ¶þÕ¡¶¼Ü¹¹¸ÅÊö¡·¿ªÊ¼£¬È»ºóÔٻص½ÕâÀï¡£

¿ªÊ¼Ö®Ç°

ÔËÐб¾Õ½ÚÖеÄÁ½¸öÀý×Ó×îµÍÒªÇóÊÇ£ºNettyµÄ×îа汾(Netty5)ºÍJDK1.6¼°ÒÔÉÏ¡£×îеÄNetty°æ±¾ÔÚÏîÄ¿ÏÂÔØÒ³Ãæ¿ÉÒÔÕÒµ½¡£ÎªÁËÏÂÔØµ½ÕýÈ·µÄJDK°æ±¾£¬Çëµ½Äãϲ»¶µÄÍøÕ¾ÏÂÔØ¡£

ÔĶÁ±¾Õ½ڹý³ÌÖУ¬Äã¿ÉÄÜ»á¶ÔÏà¹ØÀàÓÐÒɻ󣬹ØÓÚÕâЩÀàµÄÏêϸµÄÐÅÏ¢ÇëÇë²Î¿¼API˵Ã÷Îĵµ¡£ÎªÁË·½±ã£¬ËùÓÐÎĵµÖÐÉæ¼°µ½µÄÀàÃû×Ö¶¼»á±»¹ØÁªµ½Ò»¸öÔÚÏßµÄAPI˵Ã÷¡£µ±È»Èç¹ûÓÐÈκδíÎóÐÅÏ¢¡¢Óï·¨´íÎó»òÕßÄãÓÐÈκκõĽ¨ÒéÀ´¸Ä½øÎĵµËµÃ÷£¬ÄÇôÇëÁªÏµNettyÉçÇø¡£

DISCARD·þÎñ(¶ªÆú·þÎñ£¬Ö¸µÄÊÇ»áºöÂÔËùÓнÓÊÕµÄÊý¾ÝµÄÒ»ÖÖЭÒé)

ÊÀ½çÉÏ×î¼òµ¥µÄЭÒé²»ÊÇ¡±Hello,World!¡±£¬ÊÇDISCARD£¬ËûÊÇÒ»ÖÖ¶ªÆúÁËËùÓнÓÊܵ½µÄÊý¾Ý£¬²¢²»×öÓÐÈκεÄÏìÓ¦µÄЭÒé¡£

ΪÁËʵÏÖDISCARDЭÒ飬ÄãΨһÐèÒª×öµÄ¾ÍÊǺöÂÔËùÓÐÊÕµ½µÄÊý¾Ý¡£ÈÃÎÒÃÇ´Ó´¦ÀíÆ÷µÄʵÏÖ¿ªÊ¼£¬´¦ÀíÆ÷ÊÇÓÉNettyÉú³ÉÓÃÀ´´¦ÀíI/OʼþµÄ¡£

package io.netty.example.discard;
02

03
import io.netty.buffer.ByteBuf;
04

05
import io.netty.channel.ChannelHandlerContext;
06
import io.netty.channel.ChannelHandlerAdapter;
07

08
/**
09
* Handles a server-side channel.
10
*/
11
public class DiscardServerHandler extends ChannelHandlerAdapter { // (1)
12

13
@Override
14
public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)
15
// Discard the received data silently.
16
((ByteBuf) msg).release(); // (3)
17
}
18

19
@Override
20
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
21
// Close the connection when an exception is raised.
22
cause.printStackTrace();
23
ctx.close();
24
}
25
}

DisCardServerHandler ¼Ì³Ð×Ô ChannelHandlerAdapter£¬Õâ¸öÀàʵÏÖÁËChannelHandler½Ó¿Ú£¬ChannelHandlerÌṩÁËÐí¶àʼþ´¦ÀíµÄ½Ó¿Ú·½·¨£¬È»ºóÄã¿ÉÒÔ¸²¸ÇÕâЩ·½·¨¡£ÏÖÔÚ½ö½öÖ»ÐèÒª¼Ì³ÐChannelHandlerAdapterÀà¶ø²»ÊÇÄã×Ô¼ºÈ¥ÊµÏÖ½Ó¿Ú·½·¨¡£

ÕâÀïÎÒÃǸ²¸ÇÁËchanelRead()ʼþ´¦Àí·½·¨¡£Ã¿µ±´Ó¿Í»§¶ËÊÕµ½ÐµÄÊý¾Ýʱ£¬Õâ¸ö·½·¨»áÔÚÊÕµ½ÏûϢʱ±»µ÷Óã¬Õâ¸öÀý×ÓÖУ¬ÊÕµ½µÄÏûÏ¢µÄÀàÐÍÊÇByteBuf

ΪÁËʵÏÖDISCARDЭÒ飬´¦ÀíÆ÷²»µÃ²»ºöÂÔËùÓнÓÊܵ½µÄÏûÏ¢¡£ByteBufÊÇÒ»¸öÒýÓüÆÊý¶ÔÏó£¬Õâ¸ö¶ÔÏó±ØÐëÏÔʾµØµ÷ÓÃrelease()·½·¨À´ÊÍ·Å¡£Çë¼Çס´¦ÀíÆ÷µÄÖ°ÔðÊÇÊÍ·ÅËùÓд«µÝµ½´¦ÀíÆ÷µÄÒýÓüÆÊý¶ÔÏó¡£Í¨³££¬channelRead()·½·¨µÄʵÏÖ¾ÍÏñÏÂÃæµÄÕâ¶Î´úÂ룺

@Override
2
public void channelRead(ChannelHandlerContext ctx, Object msg) {
3
try {
4
// Do something with msg
5
} finally {
6
ReferenceCountUtil.release(msg);
7
}
8
}

exceptionCaught()ʼþ´¦Àí·½·¨Êǵ±³öÏÖThrowable¶ÔÏó²Å»á±»µ÷Ó㬼´µ±NettyÓÉÓÚIO´íÎó»òÕß´¦ÀíÆ÷ÔÚ´¦ÀíʼþʱÅ׳öµÄÒ쳣ʱ¡£Ôڴ󲿷ÖÇé¿öÏ£¬²¶»ñµÄÒì³£Ó¦¸Ã±»¼Ç¼ÏÂÀ´²¢ÇҰѹØÁªµÄchannel¸ø¹Ø±Õµô¡£È»¶øÕâ¸ö·½·¨µÄ´¦Àí·½Ê½»áÔÚÓöµ½²»Í¬Òì³£µÄÇé¿öÏÂÓв»Í¬µÄʵÏÖ£¬±ÈÈçÄã¿ÉÄÜÏëÔڹرÕÁ¬½Ó֮ǰ·¢ËÍÒ»¸ö´íÎóÂëµÄÏìÓ¦ÏûÏ¢¡£

µ½Ä¿Ç°ÎªÖ¹Ò»Çж¼»¹±È½Ï˳Àû£¬ÎÒÃÇÒѾ­ÊµÏÖÁËDISCARD·þÎñµÄÒ»°ë¹¦ÄÜ£¬Ê£ÏµÄÐèÒª±àдһ¸ömain()·½·¨À´Æô¶¯·þÎñ¶ËµÄDiscardServerHandler¡£

package io.netty.example.discard;
02

03
import io.netty.bootstrap.ServerBootstrap;
04

05
import io.netty.channel.ChannelFuture;
06
import io.netty.channel.ChannelInitializer;
07
import io.netty.channel.ChannelOption;
08
import io.netty.channel.EventLoopGroup;
09
import io.netty.channel.nio.NioEventLoopGroup;
10
import io.netty.channel.socket.SocketChannel;
11
import io.netty.channel.socket.nio.NioServerSocketChannel;
12

13
/**
14
* Discards any incoming data.
15
*/
16
public class DiscardServer {
17

18
private int port;
19

20
public DiscardServer(int port) {
21
this.port = port;
22
}
23

24
public void run() throws Exception {
25
EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
26
EventLoopGroup workerGroup = new NioEventLoopGroup();
27
try {
28
ServerBootstrap b = new ServerBootstrap(); // (2)
29
b.group(bossGroup, workerGroup)
30
.channel(NioServerSocketChannel.class) // (3)
31
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
32
@Override
33
public void initChannel(SocketChannel ch) throws Exception {
34
ch.pipeline().addLast(new DiscardServerHandler());
35
}
36
})
37
.option(ChannelOption.SO_BACKLOG, 128) // (5)
38
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
39

40
// Bind and start to accept incoming connections.
41
ChannelFuture f = b.bind(port).sync(); // (7)
42

43
// Wait until the server socket is closed.
44
// In this example, this does not happen, but you can do that to gracefully
45
// shut down your server.
46
f.channel().closeFuture().sync();
47
} finally {
48
workerGroup.shutdownGracefully();
49
bossGroup.shutdownGracefully();
50
}
51
}
52

53
public static void main(String[] args) throws Exception {
54
int port;
55
if (args.length > 0) {
56
port = Integer.parseInt(args[0]);
57
} else {
58
port = 8080;
59
}
60
new DiscardServer(port).run();
61
}
62
}

NioEventLoopGroup ÊÇÓÃÀ´´¦ÀíI/O²Ù×÷µÄ¶àÏß³ÌʼþÑ­»·Æ÷£¬NettyÌṩÁËÐí¶à²»Í¬µÄEventLoopGroupµÄʵÏÖÓÃÀ´´¦Àí²»Í¬´«ÊäЭÒé¡£ÔÚÕâ¸öÀý×ÓÖÐÎÒÃÇʵÏÖÁËÒ»¸ö·þÎñ¶ËµÄÓ¦Óã¬Òò´Ë»áÓÐ2¸öNioEventLoopGroup»á±»Ê¹ÓᣵÚÒ»¸ö¾­³£±»½Ð×ö¡®boss¡¯£¬ÓÃÀ´½ÓÊÕ½øÀ´µÄÁ¬½Ó¡£µÚ¶þ¸ö¾­³£±»½Ð×ö¡®worker¡¯£¬ÓÃÀ´´¦ÀíÒѾ­±»½ÓÊÕµÄÁ¬½Ó£¬Ò»µ©¡®boss¡¯½ÓÊÕµ½Á¬½Ó£¬¾Í»á°ÑÁ¬½ÓÐÅÏ¢×¢²áµ½¡®worker¡¯ÉÏ¡£ÈçºÎÖªµÀ¶àÉÙ¸öÏß³ÌÒѾ­±»Ê¹Óã¬ÈçºÎÓ³Éäµ½ÒѾ­´´½¨µÄChannelsÉ϶¼ÐèÒªÒÀÀµÓÚEventLoopGroupµÄʵÏÖ£¬²¢ÇÒ¿ÉÒÔͨ¹ý¹¹Ô캯ÊýÀ´ÅäÖÃËûÃǵĹØÏµ¡£

ServerBootstrap ÊÇÒ»¸öÆô¶¯NIO·þÎñµÄ¸¨ÖúÆô¶¯Àà¡£Äã¿ÉÒÔÔÚÕâ¸ö·þÎñÖÐÖ±½ÓʹÓÃChannel£¬µ«ÊÇÕâ»áÊÇÒ»¸ö¸´ÔӵĴ¦Àí¹ý³Ì£¬ÔںܶàÇé¿öÏÂÄã²¢²»ÐèÒªÕâÑù×ö¡£

ÕâÀïÎÒÃÇÖ¸¶¨Ê¹ÓÃNioServerSocketChannelÀàÀ´¾ÙÀý˵Ã÷Ò»¸öеÄChannelÈçºÎ½ÓÊÕ½øÀ´µÄÁ¬½Ó¡£

ÕâÀïµÄʼþ´¦ÀíÀྭ³£»á±»ÓÃÀ´´¦ÀíÒ»¸ö×î½üµÄÒѾ­½ÓÊÕµÄChannel¡£ChannelInitializerÊÇÒ»¸öÌØÊâµÄ´¦ÀíÀ࣬ËûµÄÄ¿µÄÊǰïÖúʹÓÃÕßÅäÖÃÒ»¸öеÄChannel¡£Ò²ÐíÄãÏëͨ¹ýÔö¼ÓһЩ´¦ÀíÀà±ÈÈçDiscardServerHandleÀ´ÅäÖÃÒ»¸öеÄChannel»òÕ߯ä¶ÔÓ¦µÄChannelPipelineÀ´ÊµÏÖÄãµÄÍøÂç³ÌÐò¡£µ±ÄãµÄ³ÌÐò±äµÄ¸´ÔÓʱ£¬¿ÉÄÜÄã»áÔö¼Ó¸ü¶àµÄ´¦ÀíÀൽpiplineÉÏ£¬È»ºóÌáÈ¡ÕâЩÄäÃûÀൽ×î¶¥²ãµÄÀàÉÏ¡£

Äã¿ÉÒÔÉèÖÃÕâÀïÖ¸¶¨µÄͨµÀʵÏÖµÄÅäÖòÎÊý¡£ÎÒÃÇÕýÔÚдһ¸öTCP/IPµÄ·þÎñ¶Ë£¬Òò´ËÎÒÃDZ»ÔÊÐíÉèÖÃsocketµÄ²ÎÊýÑ¡Ïî±ÈÈçtcpNoDelayºÍkeepAlive¡£Çë²Î¿¼ChannelOptionºÍÏêϸµÄChannelConfigʵÏֵĽӿÚÎĵµÒÔ´Ë¿ÉÒÔ¶ÔChannelOptionsµÄÓÐÒ»¸ö´ó¸ÅµÄÈÏʶ¡£

Äã¹Ø×¢¹ýoption()ºÍchildOption()Âð£¿option()ÊÇÌṩ¸øNioServerSocketChannelÓÃÀ´½ÓÊÕ½øÀ´µÄÁ¬½Ó¡£childOption()ÊÇÌṩ¸øÓɸ¸¹ÜµÀServerChannel½ÓÊÕµ½µÄÁ¬½Ó£¬ÔÚÕâ¸öÀý×ÓÖÐÒ²ÊÇNioServerSocketChannel¡£

ÎÒÃǼÌÐø£¬Ê£ÏµľÍÊǰ󶨶˿ÚÈ»ºóÆô¶¯·þÎñ¡£ÕâÀïÎÒÃÇÔÚ»úÆ÷Éϰó¶¨ÁË»úÆ÷ËùÓÐÍø¿¨ÉϵÄ8080¶Ë¿Ú¡£µ±È»ÏÖÔÚÄã¿ÉÒÔ¶à´Îµ÷ÓÃbind()·½·¨(»ùÓÚ²»Í¬°ó¶¨µØÖ·)¡£

¹§Ï²£¡ÄãÒѾ­Íê³ÉÊìÁ·µØÍê³ÉÁ˵ÚÒ»¸ö»ùÓÚNettyµÄ·þÎñ¶Ë³ÌÐò¡£

¹Û²ì½ÓÊÕµ½µÄÊý¾Ý

ÏÖÔÚÎÒÃÇÒѾ­±àд³öÎÒÃǵÚÒ»¸ö·þÎñ¶Ë£¬ÎÒÃÇÐèÒª²âÊÔÒ»ÏÂËûÊÇ·ñÕæµÄ¿ÉÒÔÔËÐС£×î¼òµ¥µÄ²âÊÔ·½·¨ÊÇÓÃtelnet ÃüÁî¡£ÀýÈ磬Äã¿ÉÒÔÔÚÃüÁîÐÐÉÏÊäÈëtelnet localhost 8080»òÕ߯äËûÀàÐͲÎÊý¡£

È»¶øÎÒÃÇÄÜ˵Õâ¸ö·þÎñ¶ËÊÇÕý³£ÔËÐÐÁËÂð£¿ÊÂʵÉÏÎÒÃÇÒ²²»ÖªµÀÒòΪËûÊÇÒ»¸ödiscard·þÎñ£¬Äã¸ù±¾²»¿ÉÄܵõ½ÈκεÄÏìÓ¦¡£ÎªÁËÖ¤Ã÷ËûÈÔÈ»ÊÇÔÚ¹¤×÷µÄ£¬ÈÃÎÒÃÇÐ޸ķþÎñ¶ËµÄ³ÌÐòÀ´´òÓ¡³öËûµ½µ×½ÓÊÕµ½ÁËʲô¡£

ÎÒÃÇÒѾ­ÖªµÀchannelRead()·½·¨ÊÇÔÚÊý¾Ý±»½ÓÊÕµÄʱºòµ÷Óá£ÈÃÎÒÃÇ·ÅһЩ´úÂëµ½DiscardServerHandlerÀàµÄchannelRead()·½·¨¡£

@Override
02
public void channelRead(ChannelHandlerContext ctx, Object msg) {
03
ByteBuf in = (ByteBuf) msg;
04
try {
05
while (in.isReadable()) { // (1)
06
System.out.print((char) in.readByte());
07
System.out.flush();
08
}
09
} finally {
10
ReferenceCountUtil.release(msg); // (2)
11
}
12
}

Õâ¸öµÍЧµÄÑ­»·ÊÂʵÉÏ¿ÉÒÔ¼ò»¯Îª:System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII))
»òÕߣ¬Äã¿ÉÒÔÔÚÕâÀïµ÷ÓÃin.release()¡£

Èç¹ûÄãÔÙ´ÎÔËÐÐtelnetÃüÁÄ㽫»á¿´µ½·þÎñ¶Ë´òÓ¡³öÁËËûËù½ÓÊÕµ½µÄÏûÏ¢¡£

ÍêÕûµÄdiscard server´úÂë·ÅÔÚÁËio.netty.example.discard°üÏÂÃæ¡£

ECHO·þÎñ£¨ÏìӦʽЭÒ飩

µ½Ä¿Ç°ÎªÖ¹£¬ÎÒÃÇËäÈ»½ÓÊÕµ½ÁËÊý¾Ý£¬µ«Ã»ÓÐ×öÈκεÄÏìÓ¦¡£È»¶øÒ»¸ö·þÎñ¶Ëͨ³£»á¶ÔÒ»¸öÇëÇó×÷³öÏìÓ¦¡£ÈÃÎÒÃÇѧϰÔõÑùÔÚECHOЭÒéµÄʵÏÖϱàдһ¸öÏìÓ¦ÏûÏ¢¸ø¿Í»§¶Ë£¬Õâ¸öЭÒéÕë¶ÔÈκνÓÊÕµÄÊý¾Ý¶¼»á·µ»ØÒ»¸öÏìÓ¦¡£

ºÍdiscard serverΨһ²»Í¬µÄÊǰÑÔÚ´Ë֮ǰÎÒÃÇʵÏÖµÄchannelRead()·½·¨£¬·µ»ØËùÓеÄÊý¾ÝÌæ´ú´òÓ¡½ÓÊÕÊý¾Ýµ½¿ØÖÆÌ¨ÉϵÄÂß¼­¡£Òò´Ë£¬ÐèÒª°ÑchannelRead()·½·¨ÐÞ¸ÄÈçÏ£º

@Override
2
public void channelRead(ChannelHandlerContext ctx, Object msg) {
3
ctx.write(msg); // (1)
4
ctx.flush(); // (2)
5
}

1. ChannelHandlerContext¶ÔÏóÌṩÁËÐí¶à²Ù×÷£¬Ê¹ÄãÄܹ»´¥·¢¸÷ÖÖ¸÷ÑùµÄI/OʼþºÍ²Ù×÷¡£ÕâÀïÎÒÃǵ÷ÓÃÁËwrite(Object)·½·¨À´Öð×ֵذѽÓÊܵ½µÄÏûϢдÈë¡£Çë×¢ÒⲻͬÓÚDISCARDµÄÀý×ÓÎÒÃDz¢Ã»ÓÐÊͷŽÓÊܵ½µÄÏûÏ¢£¬ÕâÊÇÒòΪµ±Ð´ÈëµÄʱºòNettyÒѾ­°ïÎÒÃÇÊÍ·ÅÁË¡£
2. ctx.write(Object)·½·¨²»»áʹÏûϢдÈ뵽ͨµÀÉÏ£¬Ëû±»»º³åÔÚÁËÄÚ²¿£¬ÄãÐèÒªµ÷ÓÃctx.flush()·½·¨À´°Ñ»º³åÇøÖÐÊý¾ÝÇ¿ÐÐÊä³ö¡£»òÕßÄã¿ÉÒÔÓøü¼ò½àµÄcxt.writeAndFlush(msg)ÒԴﵽͬÑùµÄÄ¿µÄ¡£

Èç¹ûÄãÔÙÒ»´ÎÔËÐÐtelnetÃüÁÄã»á¿´µ½·þÎñ¶Ë»á·¢»ØÒ»¸öÄãÒѾ­·¢Ë͵ÄÏûÏ¢¡£

ÍêÕûµÄecho·þÎñµÄ´úÂë·ÅÔÚÁËio.netty.example.echo°üÏÂÃæ¡£

TIME·þÎñ(ʱ¼äЭÒéµÄ·þÎñ)

ÔÚÕâ¸ö²¿·Ö±»ÊµÏÖµÄЭÒéÊÇTIMEЭÒé¡£ºÍ֮ǰµÄÀý×Ó²»Í¬µÄÊÇÔÚ²»½ÓÊÜÈκÎÇëÇóʱËû»á·¢ËÍÒ»¸öº¬32λµÄÕûÊýµÄÏûÏ¢£¬²¢ÇÒÒ»µ©ÏûÏ¢·¢Ë;ͻáÁ¢¼´¹Ø±ÕÁ¬½Ó¡£ÔÚÕâ¸öÀý×ÓÖУ¬Äã»áѧϰµ½ÈçºÎ¹¹½¨ºÍ·¢ËÍÒ»¸öÏûÏ¢£¬È»ºóÔÚÍê³ÉʱÖ÷¶¯¹Ø±ÕÁ¬½Ó¡£

ÒòΪÎÒÃǽ«»áºöÂÔÈκνÓÊÕµ½µÄÊý¾Ý£¬¶øÖ»ÊÇÔÚÁ¬½Ó±»´´½¨·¢ËÍÒ»¸öÏûÏ¢£¬ËùÒÔÕâ´ÎÎÒÃDz»ÄÜʹÓÃchannelRead()·½·¨ÁË£¬´úÌæËûµÄÊÇ£¬ÎÒÃÇÐèÒª¸²¸ÇchannelActive()·½·¨£¬ÏÂÃæµÄ¾ÍÊÇʵÏÖµÄÄÚÈÝ£º

package io.netty.example.time;
02

03
public class TimeServerHandler extends ChannelHandlerAdapter {
04

05
@Override
06
public void channelActive(final ChannelHandlerContext ctx) { // (1)
07
final ByteBuf time = ctx.alloc().buffer(4); // (2)
08
time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
09

10
final ChannelFuture f = ctx.writeAndFlush(time); // (3)
11
f.addListener(new ChannelFutureListener() {
12
@Override
13
public void operationComplete(ChannelFuture future) {
14
assert f == future;
15
ctx.close();
16
}
17
}); // (4)
18
}
19

20
@Override
21
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
22
cause.printStackTrace();
23
ctx.close();
24
}
25
}

channelActive()·½·¨½«»áÔÚÁ¬½Ó±»½¨Á¢²¢ÇÒ×¼±¸½øÐÐͨÐÅʱ±»µ÷Óá£Òò´ËÈÃÎÒÃÇÔÚÕâ¸ö·½·¨ÀïÍê³ÉÒ»¸ö´ú±íµ±Ç°Ê±¼äµÄ32λÕûÊýÏûÏ¢µÄ¹¹½¨¹¤×÷¡£

ΪÁË·¢ËÍÒ»¸öеÄÏûÏ¢£¬ÎÒÃÇÐèÒª·ÖÅäÒ»¸ö°üº¬Õâ¸öÏûÏ¢µÄÐµĻº³å¡£ÒòΪÎÒÃÇÐèҪдÈëÒ»¸ö32λµÄÕûÊý£¬Òò´ËÎÒÃÇÐèÒªÒ»¸öÖÁÉÙÓÐ4¸ö×Ö½ÚµÄByteBuf¡£Í¨¹ýChannelHandlerContext.alloc()µÃµ½Ò»¸öµ±Ç°µÄByteBufAllocator£¬È»ºó·ÖÅäÒ»¸öÐµĻº³å¡£

ºÍÍù³£Ò»ÑùÎÒÃÇÐèÒª±àдһ¸ö¹¹½¨ºÃµÄÏûÏ¢¡£µ«ÊǵÈÒ»µÈ£¬flipÔÚÄÄ£¿ÄѵÀÎÒÃÇʹÓÃNIO·¢ËÍÏûϢʱ²»Êǵ÷ÓÃjava.nio.ByteBuffer.flip()Âð£¿ByteBufÖ®ËùÒÔûÓÐÕâ¸ö·½·¨ÒòΪÓÐÁ½¸öÖ¸Õ룬һ¸ö¶ÔÓ¦¶Á²Ù×÷Ò»¸ö¶ÔӦд²Ù×÷¡£µ±ÄãÏòByteBufÀïдÈëÊý¾ÝµÄʱºòдָÕëµÄË÷Òý¾Í»áÔö¼Ó£¬Í¬Ê±¶ÁÖ¸ÕëµÄË÷ÒýûÓб仯¡£¶ÁÖ¸ÕëË÷ÒýºÍдָÕëË÷Òý·Ö±ð´ú±íÁËÏûÏ¢µÄ¿ªÊ¼ºÍ½áÊø¡£±È½ÏÆðÀ´£¬NIO»º³å²¢Ã»ÓÐÌṩһÖÖ¼ò½àµÄ·½Ê½À´¼ÆËã³öÏûÏ¢ÄÚÈݵĿªÊ¼ºÍ½á⣬³ý·ÇÄãµ÷ÓÃflip·½·¨¡£µ±ÄãÍü¼Çµ÷ÓÃflip·½·¨¶øÒýÆðûÓÐÊý¾Ý»òÕß´íÎóÊý¾Ý±»·¢ËÍʱ£¬Äã»áÏÝÈëÀ§¾³¡£ÕâÑùµÄÒ»¸ö´íÎ󲻻ᷢÉúÔÚNettyÉÏ£¬ÒòΪÎÒÃǶÔÓÚ²»Í¬µÄ²Ù×÷ÀàÐÍÓв»Í¬µÄÖ¸Õë¡£Äã»á·¢ÏÖÕâÑùµÄʹÓ÷½·¨»áÈÃÄã¹ý³Ì±äµÃ¸ü¼ÓµÄÈÝÒ×£¬ÒòΪÄãÒѾ­Ï°¹ßÒ»ÖÖûÓÐʹÓÃflipµÄ·½Ê½¡£ÁíÍâÒ»¸öµãÐèҪעÒâµÄÊÇChannelHandlerContext.write()(ºÍwriteAndFlush())·½·¨»á·µ»ØÒ»¸öChannelFuture¶ÔÏó£¬Ò»¸öChannelFuture´ú±íÁËÒ»¸ö»¹Ã»Óз¢ÉúµÄI/O²Ù×÷¡£ÕâÒâζ×ÅÈκÎÒ»¸öÇëÇó²Ù×÷¶¼²»»áÂíÉϱ»Ö´ÐУ¬ÒòΪÔÚNettyÀïËùÓеIJÙ×÷¶¼ÊÇÒì²½µÄ¡£¾Ù¸öÀý×ÓÏÂÃæµÄ´úÂëÖÐÔÚÏûÏ¢±»·¢ËÍ֮ǰ¿ÉÄÜ»áÏȹرÕÁ¬½Ó¡£

Channel ch = ...;
2
ch.writeAndFlush(message);
3
ch.close();

Òò´ËÄãÐèÒªÔÚwrite()·½·¨·µ»ØµÄChannelFutureÍê³Éºóµ÷ÓÃclose()·½·¨£¬È»ºóµ±ËûµÄд²Ù×÷ÒѾ­Íê³ÉËû»á֪ͨËûµÄ¼àÌýÕß¡£Çë×¢Òâ,close()·½·¨Ò²¿ÉÄܲ»»áÁ¢Âí¹Ø±Õ£¬ËûÒ²»á·µ»ØÒ»¸öChannelFuture¡£

µ±Ò»¸öдÇëÇóÒѾ­Íê³ÉÊÇÈçºÎ֪ͨµ½ÎÒÃÇ£¿Õâ¸öÖ»ÐèÒª¼òµ¥µØÔÚ·µ»ØµÄChannelFutureÉÏÔö¼ÓÒ»¸öChannelFutureListener¡£ÕâÀïÎÒÃǹ¹½¨ÁËÒ»¸öÄäÃûµÄChannelFutureListenerÀàÓÃÀ´ÔÚ²Ù×÷Íê³Éʱ¹Ø±ÕChannel¡£»òÕߣ¬Äã¿ÉÒÔʹÓüòµ¥µÄÔ¤¶¨Òå¼àÌýÆ÷´úÂë:

f.addListener(ChannelFutureListener.CLOSE);

ΪÁ˲âÊÔÎÒÃǵÄtime·þÎñÈçÎÒÃÇÆÚÍûµÄÒ»Ñù¹¤×÷£¬Äã¿ÉÒÔʹÓÃUNIXµÄrdateÃüÁî

	$ rdate -o <port> -p <host>

PortÊÇÄãÔÚmain()º¯ÊýÖÐÖ¸¶¨µÄ¶Ë¿Ú£¬hostʹÓÃlocahost¾Í¿ÉÒÔÁË¡£

Time¿Í»§¶Ë

²»ÏñDISCARDºÍECHOµÄ·þÎñ¶Ë£¬¶ÔÓÚTIMEЭÒéÎÒÃÇÐèÒªÒ»¸ö¿Í»§¶ËÒòΪÈËÃDz»ÄܰÑÒ»¸ö32λµÄ¶þ½øÖÆÊý¾Ý·­Òë³ÉÒ»¸öÈÕÆÚ»òÕßÈÕÀú¡£ÔÚÕâÒ»²¿·Ö£¬ÎÒÃǽ«»áÌÖÂÛÈçºÎÈ·±£·þÎñ¶ËÊÇÕý³£¹¤×÷µÄ£¬²¢ÇÒѧϰÔõÑùÓÃNetty±àдһ¸ö¿Í»§¶Ë¡£

ÔÚNettyÖÐ,±àд·þÎñ¶ËºÍ¿Í»§¶Ë×î´óµÄ²¢ÇÒΨһ²»Í¬µÄʹÓÃÁ˲»Í¬µÄBootStrapºÍChannelµÄʵÏÖ¡£Çë¿´Ò»ÏÂÏÂÃæµÄ´úÂ룺

package io.netty.example.time;
02

03
public class TimeClient {
04
public static void main(String[] args) throws Exception {
05
String host = args[0];
06
int port = Integer.parseInt(args[1]);
07
EventLoopGroup workerGroup = new NioEventLoopGroup();
08

09
try {
10
Bootstrap b = new Bootstrap(); // (1)
11
b.group(workerGroup); // (2)
12
b.channel(NioSocketChannel.class); // (3)
13
b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
14
b.handler(new ChannelInitializer&lt;SocketChannel&gt;() {
15
@Override
16
public void initChannel(SocketChannel ch) throws Exception {
17
ch.pipeline().addLast(new TimeClientHandler());
18
}
19
});
20

21
// Start the client.
22
ChannelFuture f = b.connect(host, port).sync(); // (5)
23

24
// Wait until the connection is closed.
25
f.channel().closeFuture().sync();
26
} finally {
27
workerGroup.shutdownGracefully();
28
}
29
}
30
}

BootStrapºÍServerBootstrapÀàËÆ,²»¹ýËûÊǶԷǷþÎñ¶ËµÄchannel¶øÑÔ£¬±ÈÈç¿Í»§¶Ë»òÕßÎÞÁ¬½Ó´«ÊäģʽµÄchannel¡£

Èç¹ûÄãÖ»Ö¸¶¨ÁËÒ»¸öEventLoopGroup£¬ÄÇËû¾Í»á¼´×÷Ϊһ¸ö¡®boss¡¯Ị̈߳¬Ò²»á×÷Ϊһ¸ö¡®workder¡¯Ị̈߳¬¾¡¹Ü¿Í»§¶Ë²»ÐèҪʹÓõ½¡®boss¡¯Ï̡߳£

´úÌæNioServerSocketChannelµÄÊÇNioSocketChannel,Õâ¸öÀàÔÚ¿Í»§¶Ëchannel±»´´½¨Ê±Ê¹Óá£

²»ÏñÔÚʹÓÃServerBootstrapʱÐèÒªÓÃchildOption()·½·¨£¬ÒòΪ¿Í»§¶ËµÄSocketChannelûÓи¸channelµÄ¸ÅÄî¡£

ÎÒÃÇÓÃconnect()·½·¨´úÌæÁËbind()·½·¨¡£

ÕýÈçÄã¿´µ½µÄ£¬ËûºÍ·þÎñ¶ËµÄ´úÂëÊDz»Ò»ÑùµÄ¡£ChannelHandlerÊÇÈçºÎʵÏÖµÄ?ËûÓ¦¸Ã´Ó·þÎñ¶Ë½ÓÊÜÒ»¸ö32λµÄÕûÊýÏûÏ¢£¬°ÑËû·­Òë³ÉÈËÃÇÄܶÁ¶®µÄ¸ñʽ£¬²¢´òÓ¡·­ÒëºÃµÄʱ¼ä£¬×îºó¹Ø±ÕÁ¬½Ó:

package io.netty.example.time;
02

03
import java.util.Date;
04

05
public class TimeClientHandler extends ChannelHandlerAdapter {
06
@Override
07
public void channelRead(ChannelHandlerContext ctx, Object msg) {
08
ByteBuf m = (ByteBuf) msg; // (1)
09
try {
10
long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L;
11
System.out.println(new Date(currentTimeMillis));
12
ctx.close();
13
} finally {
14
m.release();
15
}
16
}
17

18
@Override
19
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
20
cause.printStackTrace();
21
ctx.close();
22
}
23
}

ÔÚTCP/IPÖУ¬NETTY»á°Ñ¶Áµ½µÄÊý¾Ý·Åµ½ByteBufµÄÊý¾Ý½á¹¹ÖС£

ÕâÑù¿´ÆðÀ´·Ç³£¼òµ¥£¬²¢ÇҺͷþÎñ¶ËµÄÄǸöÀý×ӵĴúÂëÒ²Ïà²î²»¶à¡£È»¶ø£¬´¦ÀíÆ÷ÓÐʱºò»áÒòΪÅ׳öIndexOutOfBoundsException¶ø¾Ü¾ø¹¤×÷¡£ÔÚϸö²¿·ÖÎÒÃÇ»áÌÖÂÛΪʲô»á·¢ÉúÕâÖÖÇé¿ö¡£

Á÷Êý¾ÝµÄ´«Êä´¦Àí

Ò»¸öСµÄSocket BufferÎÊÌâ

ÔÚ»ùÓÚÁ÷µÄ´«ÊäÀï±ÈÈçTCP/IP£¬½ÓÊÕµ½µÄÊý¾Ý»áÏȱ»´æ´¢µ½Ò»¸ösocket½ÓÊÕ»º³åÀï¡£²»ÐÒµÄÊÇ£¬»ùÓÚÁ÷µÄ´«Êä²¢²»ÊÇÒ»¸öÊý¾Ý°ü¶ÓÁУ¬¶øÊÇÒ»¸ö×Ö½Ú¶ÓÁС£¼´Ê¹Äã·¢ËÍÁË2¸ö¶ÀÁ¢µÄÊý¾Ý°ü£¬²Ù×÷ϵͳҲ²»»á×÷Ϊ2¸öÏûÏ¢´¦Àí¶ø½ö½öÊÇ×÷ΪһÁ¬´®µÄ×Ö½Ú¶øÑÔ¡£Òò´ËÕâÊDz»Äܱ£Ö¤ÄãÔ¶³ÌдÈëµÄÊý¾Ý¾Í»á׼ȷµØ¶ÁÈ¡¡£¾Ù¸öÀý×Ó£¬ÈÃÎÒÃǼÙÉè²Ù×÷ϵͳµÄTCP/TPЭÒéÕ»ÒѾ­½ÓÊÕÁË3¸öÊý¾Ý°ü£º

ÓÉÓÚ»ùÓÚÁ÷´«ÊäµÄЭÒéµÄÕâÖÖÆÕͨµÄÐÔÖÊ£¬ÔÚÄãµÄÓ¦ÓóÌÐòÀï¶ÁÈ¡Êý¾ÝµÄʱºò»áÓкܸߵĿÉÄÜÐÔ±»·Ö³ÉÏÂÃæµÄƬ¶Î¡£

Òò´Ë£¬Ò»¸ö½ÓÊÕ·½²»¹ÜËûÊǿͻ§¶Ë»¹ÊÇ·þÎñ¶Ë£¬¶¼Ó¦¸Ã°Ñ½ÓÊÕµ½µÄÊý¾ÝÕûÀí³ÉÒ»¸ö»òÕß¶à¸ö¸üÓÐÒâ˼²¢ÇÒÄܹ»ÈóÌÐòµÄÒµÎñÂß¼­¸üºÃÀí½âµÄÊý¾Ý¡£ÔÚÉÏÃæµÄÀý×ÓÖУ¬½ÓÊÕµ½µÄÊý¾ÝÓ¦¸Ã±»¹¹Ôì³ÉÏÂÃæµÄ¸ñʽ£º

µÚÒ»¸ö½â¾ö·½°¸

ÏÖÔÚÈÃÎÒÃǻص½TIME¿Í»§¶ËµÄÀý×ÓÉÏ¡£ÕâÀïÎÒÃÇÓöµ½ÁËͬÑùµÄÎÊÌ⣬һ¸ö32×Ö½ÚÊý¾ÝÊǷdz£Ð¡µÄÊý¾ÝÁ¿£¬Ëû²¢²»¼ûµÃ»á±»¾­³£²ð·Öµ½µ½²»Í¬µÄÊý¾Ý¶ÎÄÚ¡£È»¶ø£¬ÎÊÌâÊÇËûȷʵ¿ÉÄܻᱻ²ð·Öµ½²»Í¬µÄÊý¾Ý¶ÎÄÚ£¬²¢ÇÒ²ð·ÖµÄ¿ÉÄÜÐÔ»áËæ×ÅͨÐÅÁ¿µÄÔö¼Ó¶øÔö¼Ó¡£

×î¼òµ¥µÄ·½°¸Êǹ¹ÔìÒ»¸öÄÚ²¿µÄ¿É»ýÀ۵Ļº³å£¬Ö±µ½4¸ö×Ö½ÚÈ«²¿½ÓÊÕµ½ÁËÄÚ²¿»º³å¡£ÏÂÃæµÄ´úÂëÐÞ¸ÄÁËTimeClientHandlerµÄʵÏÖÀàÐÞ¸´ÁËÕâ¸öÎÊÌâ

package io.netty.example.time;

import java.util.Date;

public class TimeClientHandler extends ChannelHandlerAdapter {
    private ByteBuf buf;

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        buf = ctx.alloc().buffer(4); // (1)
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        buf.release(); // (1)
        buf = null;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf m = (ByteBuf) msg;
        buf.writeBytes(m); // (2)
        m.release();

        if (buf.readableBytes() >= 4) { // (3)
            long currentTimeMillis = (buf.readInt() - 2208988800L) * 1000L;
            System.out.println(new Date(currentTimeMillis));
            ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

ChannelHandlerÓÐ2¸öÉúÃüÖÜÆÚµÄ¼àÌý·½·¨£ºhandlerAdded()ºÍhandlerRemoved()¡£Äã¿ÉÒÔÍê³ÉÈÎÒâ³õʼ»¯ÈÎÎñÖ»ÒªËû²»»á±»×èÈûºÜ³¤µÄʱ¼ä¡£

Ê×ÏÈ£¬ËùÓнÓÊÕµÄÊý¾Ý¶¼Ó¦¸Ã±»ÀÛ»ýÔÚbuf±äÁ¿Àï¡£

È»ºó£¬´¦ÀíÆ÷±ØÐë¼ì²ébuf±äÁ¿ÊÇ·ñÓÐ×ã¹»µÄÊý¾Ý£¬ÔÚÕâ¸öÀý×ÓÖÐÊÇ4¸ö×Ö½Ú£¬È»ºó´¦Àíʵ¼ÊµÄÒµÎñÂß¼­¡£·ñÔò£¬Netty»áÖØ¸´µ÷ÓÃchannelRead()µ±Óиü¶àÊý¾Ýµ½´ïÖ±µ½4¸ö×Ö½ÚµÄÊý¾Ý±»»ýÀÛ¡£

µÚ¶þ¸ö½â¾ö·½°¸

¾¡¹ÜµÚÒ»¸ö½â¾ö·½°¸ÒѾ­½â¾öÁËTime¿Í»§¶ËµÄÎÊÌâÁË£¬µ«ÊÇÐ޸ĺóµÄ´¦ÀíÆ÷¿´ÆðÀ´²»ÄÇôµÄ¼ò½à£¬ÏëÏóÒ»ÏÂÈç¹ûÓɶà¸ö×ֶαÈÈç¿É±ä³¤¶ÈµÄ×Ö¶Î×é³ÉµÄ¸üΪ¸´ÔÓµÄЭÒéʱ£¬ÄãµÄChannelHandlerµÄʵÏÖ½«ºÜ¿ìµØ±äµÃÄÑÒÔά»¤¡£

ÕýÈçÄãËùÖªµÄ£¬Äã¿ÉÒÔÔö¼Ó¶à¸öChannelHandlerµ½ChannelPipeline ,Òò´ËÄã¿ÉÒÔ°ÑÒ»Õû¸öChannelHandler²ð·Ö³É¶à¸öÄ£¿éÒÔ¼õÉÙÓ¦Óõĸ´Ôӳ̶ȣ¬±ÈÈçÄã¿ÉÒÔ°ÑTimeClientHandler²ð·Ö³É2¸ö´¦ÀíÆ÷£º

TimeDecoder´¦ÀíÊý¾Ý²ð·ÖµÄÎÊÌâ

TimeClientHandlerԭʼ°æ±¾µÄʵÏÖ

ÐÒÔ˵ØÊÇ£¬NettyÌṩÁËÒ»¸ö¿ÉÀ©Õ¹µÄÀ࣬°ïÄãÍê³ÉTimeDecoderµÄ¿ª·¢¡£

package io.netty.example.time;

public class TimeDecoder extends ByteToMessageDecoder { // (1)
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { // (2)
        if (in.readableBytes() < 4) {
            return; // (3)
        }

        out.add(in.readBytes(4)); // (4)
    }
}

ByteToMessageDecoderÊÇChannelHandlerµÄÒ»¸öʵÏÖÀ࣬Ëû¿ÉÒÔÔÚ´¦ÀíÊý¾Ý²ð·ÖµÄÎÊÌâÉϱäµÃºÜ¼òµ¥¡£

ÿµ±ÓÐÐÂÊý¾Ý½ÓÊÕµÄʱºò£¬ByteToMessageDecoder¶¼»áµ÷ÓÃdecode()·½·¨À´´¦ÀíÄÚ²¿µÄÄǸöÀÛ»ý»º³å¡£

Decode()·½·¨¿ÉÒÔ¾ö¶¨µ±ÀÛ»ý»º³åÀïûÓÐ×ã¹»Êý¾Ýʱ¿ÉÒÔÍùout¶ÔÏóÀï·ÅÈÎÒâÊý¾Ý¡£µ±Óиü¶àµÄÊý¾Ý±»½ÓÊÕÁËByteToMessageDecoder»áÔÙÒ»´Îµ÷ÓÃdecode()·½·¨¡£

Èç¹ûÔÚdecode()·½·¨ÀïÔö¼ÓÁËÒ»¸ö¶ÔÏóµ½out¶ÔÏóÀÕâÒâζ׎âÂëÆ÷½âÂëÏûÏ¢³É¹¦¡£ByteToMessageDecoder½«»á¶ªÆúÔÚÀÛ»ý»º³åÀïÒѾ­±»¶Á¹ýµÄÊý¾Ý¡£Çë¼ÇµÃÄã²»ÐèÒª¶Ô¶àÌõÏûÏ¢µ÷ÓÃdecode()£¬ByteToMessageDecoder»á³ÖÐøµ÷ÓÃdecode()Ö±µ½²»·ÅÈκÎÊý¾Ýµ½outÀï¡£

ÏÖÔÚÎÒÃÇÓÐÁíÍâÒ»¸ö´¦ÀíÆ÷²åÈëµ½ChannelPipelineÀÎÒÃÇÓ¦¸ÃÔÚTimeClientÀïÐÞ¸ÄChannelInitializer µÄʵÏÖ£º

b.handler(new ChannelInitializer&lt;SocketChannel&gt;() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TimeDecoder(), new TimeClientHandler());
}
});

Èç¹ûÄãÊÇÒ»¸ö´óµ¨µÄÈË£¬Äã¿ÉÄ᳢ܻÊÔʹÓøü¼òµ¥µÄ½âÂëÀàReplayingDecoder¡£²»¹ýÄ㻹ÊÇÐèÒª²Î¿¼Ò»ÏÂAPIÎĵµÀ´»ñÈ¡¸ü¶àµÄÐÅÏ¢¡£

public class TimeDecoder extends ReplayingDecoder {
@Override
protected void decode(
ChannelHandlerContext ctx, ByteBuf in, List<object width="300" height="150">out) {out.add(in.readBytes(4));}}

´ËÍ⣬Netty»¹ÌṩÁ˸ü¶à¿ÉÒÔÖ±½ÓÄÃÀ´ÓõĽâÂëÆ÷ʹÄã¿ÉÒÔ¸ü¼òµ¥µØÊµÏÖ¸ü¶àµÄЭÒ飬°ïÖúÄã±ÜÃ⿪·¢Ò»¸öÄÑÒÔά»¤µÄ´¦ÀíÆ÷ʵÏÖ¡£Çë²Î¿¼ÏÂÃæµÄ°üÒÔ»ñÈ¡¸ü¶à¸üÏêϸµÄÀý×Ó£º

¶ÔÓÚ¶þ½øÖÆÐ­ÒéÇë¿´io.netty.example.factorial

¶ÔÓÚ»ùÓÚÎı¾Ð­ÒéÇë¿´io.netty.example.telnet

ÓÃPOJO´úÌæByteBuf

ÎÒÃÇÒѾ­ÌÖÂÛÁËËùÓеÄÀý×Ó£¬µ½Ä¿Ç°ÎªÖ¹Ò»¸öÏûÏ¢µÄÏûÏ¢¶¼ÊÇʹÓÃByteBuf×÷Ϊһ¸ö»ù±¾µÄÊý¾Ý½á¹¹¡£ÔÚÕâÒ»²¿·Ö£¬ÎÒÃÇ»á¸Ä½øTIMEЭÒéµÄ¿Í»§¶ËºÍ·þÎñ¶ËµÄÀý×Ó£¬ÓÃPOJOÌæ´úByteBuf¡£ÔÚÄãµÄChannelHandlerSÖÐʹÓÃPOJOÓÅÊÆÊDZȽÏÃ÷ÏԵġ£Í¨¹ý´ÓChannelHandlerÖÐÌáÈ¡³öByteBufµÄ´úÂ룬½«»áʹChannelHandlerµÄʵÏÖ±äµÃ¸ü¼Ó¿Éά»¤ºÍ¿ÉÖØÓá£ÔÚTIME¿Í»§¶ËºÍ·þÎñ¶ËµÄÀý×ÓÖУ¬ÎÒÃǶÁÈ¡µÄ½ö½öÊÇÒ»¸ö32λµÄÕûÐÎÊý¾Ý£¬Ö±½ÓʹÓÃByteBuf²»»áÊÇÒ»¸öÖ÷ÒªµÄÎÊÌ⡣Ȼºó£¬Äã»á·¢ÏÖµ±ÄãÐèҪʵÏÖÒ»¸öÕæÊµµÄЭÒ飬·ÖÀë´úÂë±äµÃ·Ç³£µÄ±ØÒª¡£Ê×ÏÈ£¬ÈÃÎÒÃǶ¨ÒåÒ»¸öеÄÀàÐͽÐ×öUnixTime¡£

package io.netty.example.time;

import java.util.Date;

public class UnixTime {

    private final int value;

    public UnixTime() {
        this((int) (System.currentTimeMillis() / 1000L + 2208988800L));
    }

    public UnixTime(int value) {
        this.value = value;
    }

    public int value() {
        return value;
    }

    @Override
    public String toString() {
        return new Date((value() - 2208988800L) * 1000L).toString();
    }
}

ÏÖÔÚÎÒÃÇ¿ÉÒÔÐÞ¸ÄÏÂTimeDecoderÀ࣬·µ»ØÒ»¸öUnixTime£¬ÒÔÌæ´úByteBuf

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (in.readableBytes() < 4) {
return;
} out.add(new UnixTime(in.readInt()));
}

ÏÂÃæÊÇÐ޸ĺóµÄ½âÂëÆ÷£¬TimeClientHandler²»ÔÙÓÐÈκεÄByteBuf´úÂëÁË¡£

@Override
2
public void channelRead(ChannelHandlerContext ctx, Object msg) {
3
UnixTime m = (UnixTime) msg;
4
System.out.println(m);
5
ctx.close();
6
}

ÊDz»ÊDZäµÃ¸ü¼Ó¼òµ¥ºÍÓÅÑÅÁË£¿ÏàͬµÄ¼¼Êõ¿ÉÒÔ±»ÔËÓõ½·þÎñ¶Ë¡£ÈÃÎÒÃÇÐÞ¸ÄÒ»ÏÂTimeServerHandlerµÄ´úÂë¡£

@Override
2
public void channelActive(ChannelHandlerContext ctx) {
3
ChannelFuture f = ctx.writeAndFlush(new UnixTime());
4
f.addListener(ChannelFutureListener.CLOSE);
5
}

ÏÖÔÚ£¬½ö½öÐèÒªÐ޸ĵÄÊÇChannelHandlerµÄʵÏÖ£¬ÕâÀïÐèÒª°ÑUnixTime¶ÔÏóÖØÐÂת»¯ÎªÒ»¸öByteBuf¡£²»¹ýÕâÒѾ­ÊǷdz£¼òµ¥ÁË£¬ÒòΪµ±Äã¶ÔÒ»¸öÏûÏ¢±àÂëµÄʱºò£¬Äã²»ÐèÒªÔÙ´¦Àí²ð°üºÍ×é×°µÄ¹ý³Ì¡£

package io.netty.example.time;
02

03
public class TimeEncoder extends ChannelHandlerAdapter {
04
@Override
05
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
06
UnixTime m = (UnixTime) msg;
07
ByteBuf encoded = ctx.alloc().buffer(4);
08
encoded.writeInt(m.value());
09
ctx.write(encoded, promise); // (1)
10
}
11
}

ÔÚÕ⼸ÐдúÂëÀﻹÓм¸¸öÖØÒªµÄÊÂÇé¡£µÚÒ»£¬ ͨ¹ýChannelPromise£¬µ±±àÂëºóµÄÊý¾Ý±»Ð´µ½ÁËͨµÀÉÏNetty¿ÉÒÔͨ¹ýÕâ¸ö¶ÔÏó±ê¼ÇÊdzɹ¦»¹ÊÇʧ°Ü¡£µÚ¶þ£¬ ÎÒÃDz»ÐèÒªµ÷ÓÃcxt.flush()¡£ÒòΪ´¦ÀíÆ÷ÒѾ­µ¥¶À·ÖÀë³öÁËÒ»¸ö·½·¨void flush(ChannelHandlerContext cxt),Èç¹ûÏñ×Ô¼ºÊµÏÖflush·½·¨ÄÚÈÝ¿ÉÒÔ×ÔÐи²¸ÇÕâ¸ö·½·¨¡£

½øÒ»²½¼ò»¯²Ù×÷£¬Äã¿ÉÒÔʹÓÃMessageToByteEncode:

public class TimeEncoder extends MessageToByteEncoder<UnixTime> {
2
@Override
3
protected void encode(ChannelHandlerContext ctx, UnixTime msg, ByteBuf out) {
4
out.writeInt(msg.value());
5
}
6
}

×îºóµÄÈÎÎñ¾ÍÊÇÔÚTimeServerHandler֮ǰ°ÑTimeEncoder²åÈëµ½ChannelPipeline¡£µ«ÕâÊDz»ÄÇÃ´ÖØÒªµÄ¹¤×÷¡£

¹Ø±ÕÄãµÄÓ¦ÓÃ

¹Ø±ÕÒ»¸öNettyÓ¦ÓÃÍùÍùÖ»ÐèÒª¼òµ¥µØÍ¨¹ýshutdownGracefully()·½·¨À´¹Ø±ÕÄã¹¹½¨µÄËùÓеÄNioEventLoopGroupS.µ±EventLoopGroup±»ÍêÈ«µØÖÕÖ¹,²¢ÇÒ¶ÔÓ¦µÄËùÓÐchannels¶¼ÒѾ­±»¹Ø±Õʱ£¬Netty»á·µ»ØÒ»¸öFuture¶ÔÏó¡£

¸ÅÊö

ÔÚÕâÒ»Õ½ÚÖУ¬ÎÒÃÇ»á¿ìËٵػعËÏÂÈç¹ûÔÚÊìÁ·ÕÆÎÕNettyµÄÇé¿öϱàд³öÒ»¸ö½¡×³ÄÜÔËÐеÄÍøÂçÓ¦ÓóÌÐò¡£ÔÚNetty½ÓÏÂÈ¥µÄÕ½ÚÖл¹»áÓиü¶à¸üÏàÐŵÄÐÅÏ¢¡£ÎÒÃÇÒ²¹ÄÀøÄãÈ¥ÖØÐ¸´Ï°ÏÂÔÚio.netty.example°üϵÄÀý×Ó¡£Çë×¢ÒâÉçÇøÒ»Ö±ÔڵȴýÄãµÄÎÊÌâºÍÏë·¨ÒÔ°ïÖúNettyµÄ³ÖÐø¸Ä½ø£¬NettyµÄÎĵµÒ²ÊÇ»ùÓÚÄãÃǵĿìËÙ·´À¡ÉÏ¡£

   
4105 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

Java ÖеÄÖÐÎıàÂëÎÊÌâ
Java»ù´¡ÖªÊ¶µÄÈýÊ®¸ö¾­µäÎÊ´ð
Íæ×ª Java Web Ó¦Óÿª·¢
ʹÓÃSpring¸üºÃµØ´¦ÀíStruts
ÓÃEclipse¿ª·¢iPhone WebÓ¦ÓÃ
²å¼þϵͳ¿ò¼Ü·ÖÎö

Struts+Spring+Hibernate
»ùÓÚJ2EEµÄWeb 2.0Ó¦Óÿª·¢
J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Java EE 5ÆóÒµ¼¶¼Ü¹¹Éè¼Æ
Javaµ¥Ôª²âÊÔ·½·¨Óë¼¼Êõ
Java±à³Ì·½·¨Óë¼¼Êõ

Struts+Spring+Hibernate/EJB+ÐÔÄÜÓÅ»¯
»ªÏÄ»ù½ð ActiveMQ Ô­ÀíÓë¹ÜÀí
ijÃñº½¹«Ë¾ Java»ù´¡±à³Ìµ½Ó¦Óÿª·¢
ij·çµç¹«Ë¾ Java Ó¦Óÿª·¢Æ½Ì¨ÓëÇ¨ÒÆ
ÈÕÕÕ¸Û J2EEÓ¦Óÿª·¢¼¼Êõ¿ò¼ÜÓëʵ¼ù
ij¿ç¹ú¹«Ë¾ ¹¤×÷Á÷¹ÜÀíJBPM
¶«·½º½¿Õ¹«Ë¾ ¸ß¼¶J2EE¼°ÆäÇ°ÑØ¼¼Êõ