![](/img/trans.png)
[英]How to send ISO message Object from client to Netty server in java
[英]Java netty client cannot send message to server, but telnet to sever ok
我只是在學習Java Netty,以通過套接字7000使客戶端服務器變得非常簡單。服務器正在運行,它將回顯從客戶端收到的消息。 如果我使用telnet localhost 7000並將消息發送到服務器並接收回顯消息,則它可以工作。
但是,對於Java Netty客戶端,它不起作用。 服務器什么都沒收到,客戶端什么也沒發送? 當我嘗試向控制台添加一些文字時。
這是此示例的類:
客戶
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();
}
}
因此,當我運行EchoServer時,然后運行EchoClient,EchoClient的輸出為
Sending message: message from client.
Message sent successfully.
Then application stopped.
從EchoServer的輸出是
Sending message: message from server.
在您的代碼中, DelimiterBasedFrameDecoder
處理程序位於解碼器/編碼器之前。 因此,如果傳輸的消息沒有預期的定界符(例如,在這種情況下為新行),則兩個客戶端/服務器將繼續等待並認為該消息仍在傳輸。 因此,有兩種方法可以解決您的問題。
new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter())
EchoClientHandler類
public class EchoClientHandler extends SimpleChannelInboundHandler<String> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String message = "message from client.";
System.out.println("Sending message: " + message);
ctx.writeAndFlush(message + System.lineSeparator());
}
@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);
}
}
EchoServerHandler類
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.writeAndFlush(message + System.lineSeparator());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
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.writeAndFlush(message + System.lineSeparator());
}
}
服務器輸出
Server is listening on port 7000.
Sending message: message from server.
Received message: message from client.
客戶輸出
Sending message: message from client.
Received message: message from server.
Received message: message from client.
比較您的客戶端和telnet之間的協議(使用LoggingHandler或Wireshark),如果這樣做,您會注意到這2個協議之間有1個主要區別。
不同之處在於,您發送的消息末尾沒有換行符,而telnet卻沒有。
通過在消息末尾添加新的換行符,或編寫一個自動為您執行此操作的新處理程序,即可輕松解決此問題。
ctx.write(message + "\n");
您可以進行的另一個改進是調用writeAndFlush
而不是先寫然后刷新,這還可以防止您在編碼時被中斷而錯過對另一個方法的調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.