Java Nettyを学ぶだけで、ソケット7000経由で非常に単純なクライアント/サーバを作成できます。これは、telnet localhost 7000を使用してサーバーにメッセージを送信し、エコーメッセージを受信すると機能します。Java nettyクライアントはサーバにメッセージを送信できませんが、telnetでサーバを切断することができます
ただし、Java Nettyクライアントでは動作しません。サーバは何も受け取らない、クライアントは何も送らない?私はコンソールにいくつかの文章を追加しようとしました。ここで
は、この例のクラスである:私はEchoServerを実行すると、その後、私はEchoClientを実行
クライアント
public final class EchoClient {
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(
new LoggingHandler(LogLevel.TRACE),
new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()),
new StringEncoder(),
new StringDecoder(),
new EchoClientHandler());
}
});
// Start the connection attempt.
bootstrap.connect("localhost", 7000).sync().channel().closeFuture().sync();
System.out.println("Message sent successfully.");
} finally {
group.shutdownGracefully();
}
}
}
public class EchoClientHandler extends SimpleChannelInboundHandler<String> {
/**
* Constructor for the class
*
* @param message the message you want to transmit
*/
public EchoClientHandler() {
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String message = "message from client.";
System.out.println("Sending message: " + message);
ctx.write(message);
ctx.flush();
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
System.out.println("Error caught in the communication service: " + cause);
ctx.close();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("Received message: " + msg);
}
}
サーバー
public final class EchoServer {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", "7000"));
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.TRACE))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(
new LoggingHandler(LogLevel.TRACE),
new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()),
new StringEncoder(),
new StringDecoder(),
new EchoServerHandler());
}
});
System.out.println("Server is listening on port 7000.");
// Start the server.
ChannelFuture channelFuture = serverBootstrap.bind("localhost", 7000).sync();
// Wait until the server socket is closed.
channelFuture.channel().closeFuture().sync();
} finally {
// Shut down all event loops to terminate all threads.
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class EchoServerHandler extends SimpleChannelInboundHandler<String> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String message = "message from server.";
System.out.println("Sending message: " + message);
ctx.write(message);
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// Close the connection when an exception is raised.
System.out.println("Error in receiving message.");
cause.printStackTrace();
ctx.close();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, String message) throws Exception {
System.out.println("Received message: " + message);
ctx.write(message);
ctx.flush();
//ctx.close();
}
}
だから、EchoClientからの出力は
ですSending message: message from client.
Message sent successfully.
Then application stopped.
そしてEchoServerからの出力は
Sending message: message from server.
localhost 7000にtelnetしてサーバーにメッセージを書き込み、コンソールにエコーメッセージを受信できます。 –
クライアント側の 'channelActive()'の 'ctx.close()'を削除して、もう一度やり直してください。書き込みは非同期なので、書き込みが完了する前にチャンネルが閉じられる可能性があります。 – Apolozeus
@Apolozeusはい、そうですが、このctx.close()はクライアントを停止しますが、クライアントが停止しても応答がありません。接続が同じシステム上にあり、非常に単純なメッセージ転送のときは、このようにすべきではありません。 –