Tengo un cliente TCP que se conectan a un mainframe de edad (52 años) que envían y reciben la solicitud y la respuesta de ella.
Aquí es parte de conexión del núcleo de la mi cliente,
public class SimpleConnector {
private String carrier;
private SocketChannel socketChannel;
public static final byte END_OF_MESSAGE_BYTE = (byte) 0x2b;
public SimpleConnector(String carrier, InetSocketAddress inetSocketAddress) throws IOException {
this.carrier = this.carrier;
socketChannel = SocketChannel.open();
socketChannel.socket().connect(inetSocketAddress, 30000);
}
public void shutDown() throws IOException {
this.socketChannel.close();
}
//Send Request
public String sendRequest(String request) throws Exception {
final CharsetEncoder charsetEncoder = Charset.forName("ISO-8859-1").newEncoder();
int requestLength = 12 + request.length() + 1;
ByteBuffer buffer = ByteBuffer.allocate(requestLength);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.putInt(requestLength);
buffer.put(charsetEncoder.encode(CharBuffer.wrap(carrier)));
buffer.put(charsetEncoder.encode(CharBuffer.wrap(request)));
buffer.put(END_OF_MESSAGE_BYTE);
buffer.flip();
socketChannel.write(buffer);
return readResponse();
}
//Read Response
protected String readResponse() throws Exception {
CharsetDecoder charsetDecoder = Charset.forName("ISO-8859-1").newDecoder();
int responseHeaderLength = 12;
ByteBuffer responseHeaderBuf = ByteBuffer.allocate(responseHeaderLength);
responseHeaderBuf.order(ByteOrder.BIG_ENDIAN);
int bytesRead = 0;
do {
bytesRead = socketChannel.read(responseHeaderBuf);
} while (bytesRead!=-1 && responseHeaderBuf.position()<responseHeaderLength);
if (bytesRead==-1) {
throw new IOException(carrier + " : Remote connection closed unexpectedly");
}
responseHeaderBuf.flip();
int lengthField = responseHeaderBuf.getInt();
int responseLength = lengthField - responseHeaderLength;
responseHeaderBuf.clear();
ByteBuffer responseBuf = ByteBuffer.allocate(responseLength);
bytesRead = socketChannel.read(responseBuf);
if (bytesRead>responseBuf.limit() || bytesRead ==-1) {
throw new IOException(carrier + " : Remote connection closed unexpectedly");
}
responseBuf.flip();
if (responseBuf.get(responseBuf.limit()-1)==END_OF_MESSAGE_BYTE) {
responseBuf.limit(responseBuf.limit()-1);
}
responseBuf.clear();
String response = charsetDecoder.decode(responseBuf).toString();
return response;
}
public static void main(String[] args) throws Exception{
SimpleConnector simpleConnector = new SimpleConnector("carrier",new InetSocketAddress("localhost",9999));
String response=simpleConnector.sendRequest("Request");
System.out.println(response);
}
}
Estoy intentando volver a escribir la siguiente pieza utilizando Netty. Mediante el uso siguiente tutorial como referencia.
- http://tutorials.jenkov.com/netty/netty-tcp-client.html
- https://www.baeldung.com/netty
- https://github.com/deepanprabhu/netty-twoway-tcp-client-server
El problema que estoy enfrentando es que era capaz de conectar con el servidor, pero no sabía leer ni escribir de ella. Estoy usando una ChannelInboundHandlerAdapter
para hacer las operaciones de lectura y escritura.
Aquí está mi cliente Netty
public class NettyClient {
int port;
Channel channel;
EventLoopGroup workGroup = new NioEventLoopGroup();
public NettyClient(int port){
this.port = port;
}
public ChannelFuture connectLoop() throws Exception {
try{
Bootstrap b = new Bootstrap();
b.group(workGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
ChannelFuture channelFuture = b.connect("remote-ip", this.port).sync();
this.channel = channelFuture.channel();
return channelFuture;
}finally{
}
}
public void shutdown(){
workGroup.shutdownGracefully();
}
public static void main(String[] args) throws Exception{
try {
NettyClient nettyClient = new NettyClient(12000);
ChannelFuture channelFuture = nettyClient.connectLoop();
System.out.println("Sleep 2sec");
Thread.sleep(2000);
String command ="username";
final Charset charset = Charset.forName("ISO-8859-1");
int length = 13 + command.length();
if (channelFuture.isSuccess()) {
ByteBuf byteBuf = Unpooled.buffer(1024);
byteBuf.writeInt(length);
byteBuf.writeCharSequence("Some Info",charset);
byteBuf.writeCharSequence(command,charset);
channelFuture.channel().writeAndFlush(byteBuf).addListener(new ListenerImpl());
}
}
catch(Exception e){
System.out.println(e.getMessage());
System.out.println("Try Starting Server First !!");
}
finally {
}
}
private static final class ListenerImpl implements ChannelFutureListener{
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()){
System.out.println("Success"); //I can see success in Listener after write, but couldn't read response
}else {
System.out.println("Failed");
}
}
}
}
Manipulador
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
super.channelReadComplete(ctx);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("NettyClientHandler : channelRead" );
ByteBuf byteBuf = (ByteBuf) msg;
String message = byteBuf.toString(Charset.defaultCharset());
System.out.println("Received Message : " + message);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
System.out.println("NettyClientHandler : channelActive" );
}
}
Al principio me pareció Netty sólo funcionará con Netty servers.But esta respuesta clara mi duda sobre eso
Funciona un cliente Netty sólo con un servidor de Netty?
Me puede guiar a alguien, lo que estoy haciendo mal ???
Creo que el problema es con su ClientHandler. usted debe writeAndFlush()
de channelActive
método invocado cuando una conexión se ha establecido entre el servidor y el cliente TCP. Utilice el siguiente código actualizada y ver si se soluciona el problema.
@Sharable
public class NettyClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
String message = byteBuf.toString(Charset.defaultCharset());
System.out.println("Received Message : " + message);
}
@Override
public void channelActive(ChannelHandlerContext channelHandlerContext){
channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer("Netty Rocks!", CharsetUtil.UTF_8));
}
}