미나, Netty, Twisted와 함께 배우기(1): 간단한 TCP 서버 구현
8508 단어 Java 언어MinaNettyTwisted 같이 배워요.
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.
(Twisted 홈페이지의 문안이 전문적이지 않은데 asynchronous를 쓰지 않는다니)
위의 간단한 소개에서 이들의 공통된 특징인 이벤트-driven과 asynchronous를 발견할 수 있다.그것들은 모두 이벤트 구동, 비동기적인 네트워크 프로그래밍 프레임워크이다.이를 통해 알 수 있듯이 그들 사이의 공통점은 여전히 매우 뚜렷하다.그래서 저는 이 세 가지 틀을 함께 놓고 같은 기능을 실현하면 소량의 정력으로 세 가지 물건을 배울 수 있을 뿐만 아니라 그것들 간의 각 방면의 대비도 할 수 있습니다.
그 중에서 MINA와 Netty는 자바 언어를 기반으로 하고 Twisted는 Python 언어를 기반으로 한다.그러나 언어는 중점이 아니라 이념이 중점이다.
전통적인 BIO(Blocking IO/IO 차단)를 사용하여 네트워크 프로그래밍을 할 때 네트워크 IO 읽기와 쓰기를 할 때 현재 라인을 막는다. 만약에 TCP 서버를 실현한다면 모든 클라이언트 연결에 하나의 라인을 열어야 한다. 많은 라인이 어리석게 막히고 읽기와 쓰기를 기다리는 데이터로 시스템 자원의 소모가 크다.
한편, NIO(Non-Blocking IO/비차단 IO)나 AIO(Asynchronous IO/비동기 IO)는 IO 다중 복용 기술을 통해 이루어진다. 모든 연결에 하나의 라인을 만들 필요가 없다. 그 밑바닥 실현은 운영체제의 일부 특성인 select,poll,epoll,iocp 등을 통해 이루어진다.이 세 개의 네트워크 프레임워크는 모두 이것을 바탕으로 실현된다.
다음은 이 세 가지 프레임워크로 가장 간단한 TCP 서버를 구현합니다.클라이언트가 보낸 문자열을 받은 후 클라이언트에게 응답으로 문자열을 다시 씁니다.
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();
}
//
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
//
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"));
//
byte[] responseByteArray = " ".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");
}
}
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 {
//
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
try {
//
ByteBuf in = (ByteBuf) msg;
System.out.println("channelRead:" + in.toString(CharsetUtil.UTF_8));
//
byte[] responseByteArray = " ".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();
}
}
Twisted:
# -*- coding:utf-8 –*-
from twisted.internet.protocol import Protocol
from twisted.internet.protocol import Factory
from twisted.internet import reactor
class TcpServerHandle(Protocol):
#
def connectionMade(self):
print 'connectionMade'
#
def connectionLost(self, reason):
print 'connectionLost'
#
def dataReceived(self, data):
print 'dataReceived', data
self.transport.write(' ')
factory = Factory()
factory.protocol = TcpServerHandle
reactor.listenTCP(8080, factory)
reactor.run()
위의 코드에서 알 수 있듯이 이 세 프레임워크가 실현된 TCP 서버는 연결이 구축되고 클라이언트가 전송한 데이터를 수신하며 연결이 닫힐 때 어떤 이벤트를 촉발한다.예를 들어 클라이언트가 전송한 데이터를 수신할 때 MINA는 이벤트를 터치하여 메시지 리셋을 호출하고, Netty는 채널 리셋을 호출하며, Twisted는 데이터 리셋을 호출합니다.코드를 작성할 때, 하나의 클래스를 계승하고 응답을 다시 쓰는 방법만 있으면 된다.이것이 바로 이벤트-driven 이벤트 드라이브입니다.
다음은 Java가 작성한 TCP 클라이언트입니다. 클라이언트는 이 세 가지 프레임워크를 사용하지 않았고 NIO를 사용하지 않았습니다. 일반적인 BIO의 TCP 클라이언트입니다.
TCP는 연결 해제에 대한 연결을 설정하는 과정에서 여러 번 데이터를 전송하고 수신할 수 있습니다.다음 클라이언트는 두 개의 문자열을 서버에 보내고 서버가 응답하는 데이터를 두 번 가져옵니다.sleep(5000) 간격 5초.
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();
//
out.write(" ".getBytes("UTF-8"));
out.flush();
// ,
byte[] byteArray = new byte[1024];
int length = in.read(byteArray);
System.out.println(new String(byteArray, 0, length, "UTF-8"));
Thread.sleep(5000);
//
out.write(" ".getBytes("UTF-8"));
out.flush();
// ,
byteArray = new byte[1024];
length = in.read(byteArray);
System.out.println(new String(byteArray, 0, length, "UTF-8"));
} finally {
//
in.close();
out.close();
socket.close();
}
}
}
클라이언트를 사용하여 위의 세 개의 TCP 서버를 각각 테스트합니다.
MINA 서버 출력 결과:
sessionCreatedmessageReceived: 첫 번째 요청 messageReceived: 두 번째 요청 sessionClosed
Netty 서버 출력 결과:
channelActivechannelRead: 첫 번째 요청 channelRead: 두 번째 요청 channelInactive
Twisted 서버 출력 결과:
connectionMadedataReceived: 첫 번째 요청 dataReceived: 두 번째 요청 connectionLost
작가: 포크형 전재 출처 밝혀주세요:http://blog.csdn.net/xiao__gui/article/details/38581355
MINA, Netty, Twisted와 함께
MINA, Netty, Twisted 함께 배우기(1): 간단한 TCP 서버 구현
MINA, Netty, Twisted 함께 배우기(2): TCP 메시지 경계 문제 및 행별 메시지 분할
MINA, Netty, Twisted 함께 배우기 (3): TCP 메시지 고정 크기 접두사(Header)
MINA, Netty, Twisted 함께 배우기 (4): 맞춤형 프로토콜
MINA, Netty, Twisted 함께 배우기 (5): 통합 프로토타입
MINA, Netty, Twisted 함께 배우기 (6): session
MINA, Netty, Twisted 함께 배우기(7): 게시/구독(Publish/Subscribe)
MINA, Netty, Twisted 함께 배우기 (8): HTTP 서버
MINA, Netty, Twisted 함께 배우기 (9): 비동기 IO 및 콜백 함수
MINA, Netty, Twisted 함께 배우기 (10): 스레드 모델
MINA, Netty, Twisted 함께 배우기(11): SSL/TLS
MINA, Netty, Twisted 함께 배우기(12): HTTPS
원본 코드
https://github.com/wucao/mina-netty-twisted
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 내부 클래스와 익명 내부 클래스의 차이클래스 A는 클래스 B의 멤버에 직접 액세스해야 하고 클래스 B는 클래스 A의 객체를 만들어야 합니다.이때 디자인과 접근을 편리하게 하기 위해 A클래스를 B클래스에 직접 정의한다.됐어요.Class A를 내부 클래스라...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.