Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Netty, MINA, Twisted learn Series 01: implement a simple TCP server

2025-04-06 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

The article has been authorized by the author

Why do MINA, Netty and Twisted study together? First of all, you might as well take a look at the introduction to them on their official websites.

MINA:

Apache MINA is a network application framework which helps users develop high performance and high scalability network applications easily. It provides an abstract event-driven asynchronous API over various transports such as TCP/IP and UDP/IP via Java NIO.

Netty:

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

Twisted:

Twisted is an event-driven networking engine written in Python and licensed under the open source MIT license.

From the brief introduction above, Twisted officers can find their common features: event-driven and asynchronous. They are all event-driven, asynchronous network programming frameworks. Thus it can be seen that the common ground between them is still very obvious. So I put these three frameworks together to achieve the same function, not only can use a small amount of fine mechanics of three things, but also can compare them in all aspects. The copywriter of the net is not professional, ah, unexpectedly do not write asynchronous.

From the brief introduction above, we can find their common features: event-driven and asynchronous. They are all event-driven, asynchronous network programming frameworks. Thus it can be seen that the common ground between them is still very obvious. So I put these three frameworks together to achieve the same function, not only can use a small amount of fine mechanics of three things, but also can compare them in all aspects.

MINA and Netty are based on the Java language, while Twisted is based on the Python language. But language is not the point, the point is the idea.

When using traditional BIO (Blocking IO/ blocking IO) for network programming, the current thread will be blocked when reading and writing network IO. If you implement a TCP server, you need to open a thread for each client connection, and many threads may be foolishly blocking waiting for reading and writing data, which consumes a lot of system resources.

While NIO (Non-Blocking IO/ non-blocking IO) or AIO (Asynchronous IO/ Asynchronous IO) is realized by IO multiplexing technology, which does not need to create a thread for each connection, and its underlying implementation is through some features of the operating system, such as select, poll, epoll, iocp and so on. These three network frameworks are all based on this.

Let's use these three frameworks to implement the simplest TCP server. When a string is received from the client, a string is written back to the client as a response.

Netty:

Public class TcpServer {

Public static void main (String [] args) throws InterruptedException {

EventLoopGroup bossGroup = new NioEventLoopGroup ()

EventLoopGroup workerGroup = new NioEventLoopGroup ()

Try {

ServerBootstrap b = new ServerBootstrap ()

B.group (bossGroup, workerGroup)

.channel (NioServerSocketChannel.class)

.childHandler (new ChannelInitializer () {

@ Override

Public void initChannel (SocketChannel ch)

Throws Exception {

Ch.pipeline () .addLast (new TcpServerHandler ()

}

});

ChannelFuture f = b.bind (8080) .sync ()

F.channel (). CloseFuture (). Sync ()

} finally {

WorkerGroup.shutdownGracefully ()

BossGroup.shutdownGracefully ()

}

}

}

Class TcpServerHandler extends ChannelInboundHandlerAdapter {

/ / New data received

@ Override

Public void channelRead (ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {

Try {

/ / receive data from the client

ByteBuf in = (ByteBuf) msg

System.out.println ("channelRead:" + in.toString (CharsetUtil.UTF_8))

/ / send to the client

Byte [] responseByteArray = "Hello" .getBytes ("UTF-8")

ByteBuf out = ctx.alloc () .buffer (responseByteArray.length)

Out.writeBytes (responseByteArray)

Ctx.writeAndFlush (out)

} finally {

ReferenceCountUtil.release (msg)

}

}

@ Override

Public void channelActive (ChannelHandlerContext ctx) {

System.out.println ("channelActive")

}

@ Override

Public void channelInactive (ChannelHandlerContext ctx) {

System.out.println ("channelInactive")

}

@ Override

Public void exceptionCaught (ChannelHandlerContext ctx, Throwable cause) {

Cause.printStackTrace ()

Ctx.close ()

}

}

MINA:

Public class TcpServer {

Public static void main (String [] args) throws IOException {

IoAcceptor acceptor = new NioSocketAcceptor ()

Acceptor.setHandler (new TcpServerHandle ())

Acceptor.bind (new InetSocketAddress (8080))

}

}

Class TcpServerHandle extends IoHandlerAdapter {

@ Override

Public void exceptionCaught (IoSession session, Throwable cause) throws Exception {

Cause.printStackTrace ()

}

/ / New data received

@ Override

Public void messageReceived (IoSession session, Object message) throws Exception {

/ / receive data from the client

IoBuffer ioBuffer = (IoBuffer) message

Byte [] byteArray = new byte [ioBuffer.limit ()]

IoBuffer.get (byteArray, 0, ioBuffer.limit ())

System.out.println ("messageReceived:" + new String (byteArray, "UTF-8"))

/ / send to the client

Byte [] responseByteArray = "Hello" .getBytes ("UTF-8")

IoBuffer responseIoBuffer = IoBuffer.allocate (responseByteArray.length)

ResponseIoBuffer.put (responseByteArray)

ResponseIoBuffer.flip ()

Session.write (responseIoBuffer)

}

@ Override

Public void sessionCreated (IoSession session) throws Exception {

System.out.println ("sessionCreated")

}

@ Override

Public void sessionClosed (IoSession session) throws Exception {

System.out.println ("sessionClosed")

}

}

Twisted:

#-*-coding:utf-8-*-

From twisted.internet.protocol import Protocol

From twisted.internet.protocol import Factory

From twisted.internet import reactor

Class TcpServerHandle (Protocol):

# New connection establishment

Def connectionMade (self):

Print 'connectionMade'

# disconnect

Def connectionLost (self, reason):

Print 'connectionLost'

# received new data

Def dataReceived (self, data):

Print 'dataReceived', data

Self.transport.write ('Hello')

Factory = Factory ()

Factory.protocol = TcpServerHandle

Reactor.listenTCP (8080, factory)

Reactor.run ()

As can be seen from the above code, the TCP server implemented by these three frameworks will trigger an event when the connection is established, the data received from the client is received, and the connection is closed. For example, when receiving data from the client, MINA will trigger an event call messageReceived,Netty will call channelRead,Twisted and dataReceived will be called. When writing code, you only need to inherit a class and override the method of the response. This is the event-driven event driver.

The following is a TCP client written by Java for testing, the client does not use these three frameworks, nor does it use NIO, but a normal BIO TCP client.

TCP can send and receive data multiple times during the process of establishing a connection to a closed connection. The following client sends two strings to the server and gets the server response data twice, with an interval of 5 seconds via Thread.sleep (5000).

Public class TcpClient {

Public static void main (String [] args) throws IOException, InterruptedException {

Socket socket = null

OutputStream out = null

InputStream in = null

Try {

Socket = new Socket ("localhost", 8080)

Out = socket.getOutputStream ()

In = socket.getInputStream ()

/ / request server

Out.write ("first request" .getBytes ("UTF-8"))

Out.flush ()

/ / get server response and output

Byte [] byteArray = new byte [1024]

Int length = in.read (byteArray)

System.out.println (new String (byteArray, 0, length, "UTF-8"))

Thread.sleep (5000)

/ / request the server again

Out.write ("second request" .getBytes ("UTF-8"))

Out.flush ()

/ / get the server response again and output

ByteArray = new byte [1024]

Length = in.read (byteArray)

System.out.println (new String (byteArray, 0, length, "UTF-8"))

} finally {

/ / close the connection

In.close ()

Out.close ()

Socket.close ()

}

}

}

Test each of the above three TCP servers with the client to see what the results are.

MINA server output result:

SessionCreated

MessageReceived: first request

MessageReceived: second request

SessionClosed

Netty server output result:

ChannelActive

ChannelRead: first request

ChannelRead: second request

ChannelInactive

Twisted server output result:

ConnectionMade

DataReceived: first request

DataReceived: second request

ConnectionLost

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report