简单Netty服务器未发送响应

简单Netty服务器未发送响应,netty,Netty,我正在编写在TCP上运行的自定义协议搜索服务。当使用EmbeddedChannel进行测试时,一切都非常完美。为了进一步测试,我编写了一个服务器并添加了处理程序。通过来自普通java套接字客户端的请求,服务器接收数据,处理并发送回响应。但是,响应不会到达客户端套接字。我想可能是我把大管道搞砸了。因此,我将实现简化为仅一个入站处理程序。还是不行。有人能帮忙吗 服务器: public void start() throws Exception{ EventLoopGroup bossGrou

我正在编写在TCP上运行的自定义协议搜索服务。当使用EmbeddedChannel进行测试时,一切都非常完美。为了进一步测试,我编写了一个服务器并添加了处理程序。通过来自普通java套接字客户端的请求,服务器接收数据,处理并发送回响应。但是,响应不会到达客户端套接字。我想可能是我把大管道搞砸了。因此,我将实现简化为仅一个入站处理程序。还是不行。有人能帮忙吗

服务器:

public void start() throws Exception{
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    try {
        final KaiExceptionHandler kaiExceptionHandler = new KaiExceptionHandler();
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        pipeline.addLast(new SimpleHandler());
                    }
                });
        ChannelFuture future = b.bind(new InetSocketAddress("localhost", 9400)).sync();
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                if(channelFuture.isSuccess()) {
                    LOGGER.info("Kai Server is bounded to '{}'", "localhost:9400");
                }else {
                    LOGGER.error("Failed to bound Kai to 'localhost:9400'", channelFuture.cause());
                }
            }
        });
        future.channel().closeFuture().sync();
    }finally {
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }
测试客户端。一个不整洁的实现。然而,只是为了测试

public class TestClient {


public static void main(String[] args) throws Exception {

    Socket socket = new Socket("localhost", 9400);
    InputStream is = socket.getInputStream();
    StringBuilder sb = new StringBuilder();
    byte[] buffer = new byte[64];
    int r = 0;
    socket.setSoTimeout(10000);
    System.out.println("Reading...");
    while ((r = is.read(buffer)) != -1) {
        sb.append(new String(buffer).trim());
    }
    System.out.println("String: " + sb.toString());
}

}

您的测试程序假设在写入数据后连接会关闭,并且在发送多字节字符的情况下,其假设字符串不会断开

如果有意等待套接字关闭,则需要将
write
语句更改为以下内容:

ctx.write(unmooled.copiedBuffer(“客户端没有看到这个”,字符集))
.addListener(ChannelFutureListener.CLOSE);
然而,这种通信方式效率低下,因为每次您想对服务器说些什么时,都需要重新打开另一个套接字连接。最好的方法是将协议设置为基于行或由长度字段分隔,然后使用
BufferedReader
在客户端逐行读取响应,在服务器端,您应该在每条消息的末尾添加一个新行


如果服务器需要接收消息,您应该在管道的开始处添加一个
新的LineBasedFrameDecoder()
,然后添加一个可选的
新的StringDecoder()
,让netty自动将
ByteBuf
转换为字符串,您不必再这样做了。Netty也可以使用
StringEncoder
反向执行此操作,因此您可以只编写字符串对象,而不是每次都将其包装在
ByteBuf

中查看上一个问题。整个问题都与测试客户端有关。

第一个问题:
第一个由Ferrybig指出,其中
read(buffer)!=-1
要求插座关闭(感谢那位男士)。

第二个问题:
第二个是,
ChannelInboundHandlerAdapter#channelRead(ChannelHandlerContext ctx,Object msg)
永远不会被调用,因为套接字不发送任何内容,所以没有任何内容可读取。编辑我的客户发送的东西,使其工作

新客户:

public class TestClient {


public static void main(String[] args) throws Exception {

    Socket socket = new Socket("localhost", 9400);
    socket.setSoTimeout(10000);
    OutputStream raw = socket.getOutputStream();
    // Will be the request bytes
    raw.write(1);
    raw.flush();

    InputStream is = socket.getInputStream();
    StringBuilder response = new StringBuilder();
    // actual expected size will be here
    final int expectedResponse = 128; 
    byte[] buffer = new byte[expectedResponse];
    int bytesRead = is.read(buffer);
    if (bytesRead != -1) {
        response.append(new String(buffer).trim()).append("\n");
    }
    System.out.println("String: " + response.toString());
}
}

我明白了。”读取(缓冲区)!=-如果服务器关闭套接字,则1'为真。但是,我不想那样..协议是基于二进制的。请求和响应以二进制格式发送,固定的报头大小为17字节,可选的正文也是二进制格式。当我知道要从标题读取的确切响应正文大小时,是否需要分隔符?如果是,如何进行?
public class TestClient {


public static void main(String[] args) throws Exception {

    Socket socket = new Socket("localhost", 9400);
    socket.setSoTimeout(10000);
    OutputStream raw = socket.getOutputStream();
    // Will be the request bytes
    raw.write(1);
    raw.flush();

    InputStream is = socket.getInputStream();
    StringBuilder response = new StringBuilder();
    // actual expected size will be here
    final int expectedResponse = 128; 
    byte[] buffer = new byte[expectedResponse];
    int bytesRead = is.read(buffer);
    if (bytesRead != -1) {
        response.append(new String(buffer).trim()).append("\n");
    }
    System.out.println("String: " + response.toString());
}