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 是面向流的,而不是面向消息的。发件人必须明确说明消息的结束位置和下一条消息的开始位置。
我使用 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 是面向流的,而不是面向消息的。发件人必须明确说明消息的结束位置和下一条消息的开始位置。