java netty 作为 tcpServer,delphi TIdTCPClient 作为 tcpClient

java netty as tcpServer,delphi TIdTCPClient as tcpClient

我使用 java netty 作为 tcpServer 和 delphi TIdTCPClient 作为 tcpClient.the . 这是 java 编写的 tcpserver 代码:

public class NettyServer {
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<SocketChannel>() {
                    @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();
    }
}


public 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 = "hello".getBytes("UTF-8");
        ByteBuf out = ctx.alloc().buffer(responseByteArray.length);
        out.writeBytes(responseByteArray);
        ctx.writeAndFlush(out);
        //ctx.write("hello");
    } finally {
        ReferenceCountUtil.release(msg);
    }
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws  UnsupportedEncodingException{
    System.out.println("channelActive:" + ctx.channel().remoteAddress());
    ChannelGroups.add(ctx.channel());

}

@Override
public void channelInactive(ChannelHandlerContext ctx) {
    System.out.println("channelInactive:" + ctx.channel().remoteAddress());
    ChannelGroups.discard(ctx.channel());
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    cause.printStackTrace();
    ctx.close();
}

}

这里是delphi写的tcpclient代码:

  AStream := TStringStream.Create;
  IdTCPClient.IOHandler.ReadStream(AStream);

我也用

IdTCPClient.IOHandler.ReadLn()

仍然无法获取returnDATA

您的 Delphi 代码与您的 Java 代码不匹配,这就是您的客户端无法正常工作的原因。

TIdIOHandler.ReadStream() 的默认参数期望流数据前面有流长度,以字节为单位,使用网络字节顺序(大端)的 32 位或 64 位整数,具体取决于TIdIOHandler.LargeStream属性。您的 Java 代码在发送数组字节之前未发送数组长度。

TIdIOHandler.ReadLn() 的默认参数期望行数据由 CRLF 或空 LN 终止符终止。您的 Java 代码未在数组字节末尾发送任何行终止符。

简而言之,您的 Java 代码没有发送任何内容让接收方知道发送的数据实际结束的时间。除非发送数据后关闭连接,这种情况下可以将TIdIOHandler.ReadStream()AReadUntilDisconnect参数设置为true,或者使用TIdIOHandler.AllData()

TCP 是面向流的,而不是面向消息的。发件人必须明确说明消息的结束位置和下一条消息的开始位置。