![](/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.