2017-10-25 7 views
1

하나의 응용 프로그램 (서버 다음의 클라이언트)에서 TCP 에코 서버와 클라이언트를 모두 시작하려고합니다.Netty : 서버가 부트 스트랩 한 후 클라이언트를 시작하십시오. 다른 스레드가 필요한 이유는 무엇입니까?

내가 할 것은 :이 같은 server.bind().sync()에 의해 반환 ChannelFutureListener에서 클라이언트를 시작 :

public void runClientAndServer() { 
    server.run().addListener((ChannelFutureListener) future -> { 
     // client.run();      //(1) this doesn't work! 
     new Thread(()->client.run()).start(); //(2) this works! 
    }); 
} 

server.run()은 다음과 같이이다 :

public ChannelFuture run() { 
    ServerBootstrap b = new ServerBootstrap(); 
    //doing channel config stuff 
    return b.bind(6666).sync(); 
} 

client.run()이 같다 :

public void run() { 
    Bootstrap b = new Bootstrap(); 
    //do some config stuff 
    f = b.connect(host, port).sync(); //wait till connected to server 
} 

어떤 일이 발생합니까 : 잘 작동하는 문장 (2)에서; 위 문장 (1)에서 클라이언트는 Wireshark에서 볼 수있는 메시지를 보내고 서버는 TCP ACK 세그먼트를 응답하지만 서버 쪽에서는 channelRead() 메서드가 호출되지 않으며 소켓에 메시지를 쓰려고 시도 할 수 없습니다 이 캡처 같은 : wireshark capture

(4.1.16.Final를) 나는 인 Netty 스레드에 문제가 있어야합니다 생각하지만, 난 그냥

나는 최신 그물코의 버전을 기준으로 예를 준비했습니다

답변

0

을 알아낼 수 없습니다 그리고 당신이 올린 코드. 이것은 여분의 스레드없이 잘 작동합니다. 서버 나 클라이언트를 잘못 초기화 한 경우 일 수 있습니다. 나는 또한 또한 잘 작동 단일 스레드 eventloopgroup이 예를 시도

C - Initilized client 
C - write: Hey this is a test message enjoy! 
S - Channel connected: [id: 0x1d676489, L:/127.0.0.1:6666 - R:/127.0.0.1:5079] 
S - read: Hey this is a test message enjoy! 

하지만 프로그램의 기능에 영향을주지 않았다 저에게 BlockingOperationException를 던져 : 출력이 어떻게 보일지입니다

private static final NioEventLoopGroup EVENT_LOOP_GROUP = new NioEventLoopGroup(); 

private static ChannelFuture runServer() throws Exception { 
    return new ServerBootstrap() 
      .group(EVENT_LOOP_GROUP) 
      .channel(NioServerSocketChannel.class) 
      .childHandler(new ChannelInitializer<Channel>() { 

       @Override 
       protected void initChannel(Channel channel) throws Exception { 
        System.out.println("S - Channel connected: " + channel); 

        channel.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() { 

         @Override 
         protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { 
          System.out.println("S - read: " + msg.toString(StandardCharsets.UTF_8)); 
         } 
        }); 
       } 
      }) 
      .bind(6666).sync(); 
} 

private static void runClient() throws Exception { 
    new Bootstrap() 
     .group(EVENT_LOOP_GROUP) 
     .channel(NioSocketChannel.class) 
     .handler(new ChannelInitializer<Channel>() { 

      @Override 
      protected void initChannel(Channel channel) throws Exception { 
       System.out.println("C - Initilized client"); 

       channel.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() { 

        @Override 
        public void channelActive(ChannelHandlerContext ctx) throws Exception { 
         super.channelActive(ctx); 
         System.out.println("C - write: Hey this is a test message enjoy!"); 
         ctx.writeAndFlush(Unpooled.copiedBuffer("Hey this is a test message enjoy!".getBytes(StandardCharsets.UTF_8))); 
        } 

        @Override 
        protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { } 
       }); 
      } 
     }) 
     .connect("localhost", 6666).sync(); 
} 

public static void main(String[] args) throws Exception { 
    runServer().addListener(future -> { 
     runClient(); 
    }); 
} 

. 이 코드가 잘 작동해야한다면 코드를 확인하고이 예제에서 코드 방향을 잡으십시오 (이 예제에서와 같이 실제 프로젝트에 인라인 ChannelHandler를 생성하지 마십시오).