如何在不同端口上运行的特定Netty Client实例上发送数据

时间:2017-11-17 05:24:13

标签: java sockets netty

我编写了一个基本的Netty客户端,用于从服务器发送和接收数据。但我已经在端口8080和8081上启动了两个客户端实例。现在我如何在端口8080上发送特定字符串,在8081上发送另一个字符串。我对如何在特定端口上发送数据感到困惑。我可以将所有字符串发送到服务器。但是我想指定在哪个服务器的哪个端口上发送哪个字符串。就像我想在端口8080上向server1发送“Hello server1”,在端口8081上向server2发送“Hello server2”。 我怎么能这样做?

我的网络客户端

public class Client implements  Runnable {

public int port;

private Channel channel;
public  ChannelFuture channelFuture = null;
private String message;
int rcvBuf, sndBuf, lowWaterMark, highWaterMark;

public Client(int port) {

    this.port = port;
    rcvBuf = Integer.MAX_VALUE;
    sndBuf = Integer.MAX_VALUE;
    lowWaterMark = 2048;
    highWaterMark = 3048;

}

@Override
public void run() {

    try {
        connectLoop();
    } catch (Exception ex) {

        System.err.println("Exception raised in Client class" + ex);
     }

}

public final void connectLoop() throws InterruptedException {
    EventLoopGroup workGroup = new NioEventLoopGroup();

    try {
        Bootstrap bs = new Bootstrap();
        bs.group(workGroup);
        bs.channel(NioSocketChannel.class);
        bs.option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.SO_RCVBUF, rcvBuf)
                .option(ChannelOption.SO_SNDBUF, sndBuf)
                .option(ChannelOption.SO_LINGER, 0)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(lowWaterMark, highWaterMark))
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) {
                        socketChannel.pipeline()
                                .addLast("patternDecoder", new ClientDecoder())
                                .addLast("Response Handler", new ClientHandler())// for receiving from Server
                                .addLast("exception Handler", new ClientExceptionHandler(port));
                    }
                });

        channelFuture = bs.connect("127.0.0.1", port).sync();
        this.channel = channelFuture.channel();
        if (channelFuture.isSuccess()) {
            sendMessage("Hello server");
        }
    } catch (Exception ex) {

        workGroup.shutdownGracefully();
        System.err.println("ERROR : Server Not In Connection");
        System.err.println("Connecting to Server...");
                   reconnect();
    }

}

public void reconnect() throws InterruptedException {
    Thread.sleep(10000);
    connectLoop();

}

public void sendMessage(String data){
    if (data != null) 
    {
       channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer(data.getBytes()));
       System.out.println("Outgoing  To  Server  >> " + data);
    }
}
public static void main(String[] args){
    Thread t = new Thread(new Client(8080));
    t.start();
    Thread t1 = new Thread(new Client(8081));
    t1.start();
}

}

客户端处理程序

public class ClientHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, final String message) throws Exception {

        System.out.println("Incoming From Server  >> " + message);
        ctx.channel().writeAndFlush(Unpooled.wrappedBuffer("HELLO".getBytes()));
    }
}

ClientExceptionHandler

 public class ClientExceptionHandler extends ChannelInboundHandlerAdapter {

    private int port;
    public ClientExceptionHandler(int port){
        this.port = port;
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

       ctx.deregister();
       ctx.disconnect();
       ctx.close();
       System.err.println("ERROR : Server Disconnected");
       System.err.println("Reconnecting to Server...");
    }
}

1 个答案:

答案 0 :(得分:1)

首先,您需要了解端口的工作原理。只有服务器才会侦听特定端口。在您的示例中,服务器将从端口8080进行侦听。然后,多个客户端可以连接到端口8080.由于您没有给出具体的详细信息,我建议您尝试以下操作之一。

  • 运行两个服务器,一个侦听端口8080,另一个侦听端口8081.然后按照建议使用两个客户端。
  • 在端口8080上仅运行一个服务器并连接两个类似的客户端如果要区分客户端,请使用某种消息(例如,将客户端ID发送到服务器)