beykery / jkcp

kcp for java . 适用于moba,视频加速等需要极速传输场景的应用,c#版本(客户端)请参考:https://github.com/beykery/kcp4sharp
Apache License 2.0
186 stars 85 forks source link

为什么test中的实例 和netty的UDP或者TCP直接发送相比,每秒钟发送消息数不如后者多? #10

Open tidus5 opened 6 years ago

tidus5 commented 6 years ago

TestServer 和 TestClient 的 handleRecieve 都改为类似 @Override public void handleReceive(ByteBuf bb, KcpOnUdp kcp) { String content = bb.toString(Charset.forName("utf-8")); System.out.println("KCP "+ content +System.currentTimeMillis()); kcp.send(bb);// echo } 互相回发,Client的main函数中 sleep 1s 后调用close() 方法,测试下来Server端可以打印100行左右。 而用Netty直接写UDP测试1s可以打印出近2000行消息,TCP 1s 也可以打印近1800行消息。

造成这种差异的原因,是KCP算法本身调度,和增加了流量大小所致,还是别的原因?

测试DUP 用例: public class Server { private static Logger logger = LoggerFactory.getLogger(Server.class);

/**
 * udp服务端,接受客户端发送的广播
 */
public static void initServer() {
    EventLoopGroup group = new NioEventLoopGroup();
    try {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group).channel(NioDatagramChannel.class).option(ChannelOption.SO_BROADCAST, true)
                .handler(new UdpServerHandler());
        Channel channel = bootstrap.bind(AppConstants.SEARCH_PORT).sync().channel();
        channel.closeFuture().await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        group.shutdownGracefully();
    }
}

private static class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        System.out.println("UDP "+ req +System.currentTimeMillis());
        ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(req, CharsetUtil.UTF_8), msg.sender()));
    }
}

public static void main(String args[]) {
    Server.initServer();
}

}

public class Client { private static Logger logger = LoggerFactory.getLogger(Client.class); private int scanPort;

public Client(int scanPort) {
    this.scanPort = scanPort;
}

private static class ClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        String response = msg.content().toString(CharsetUtil.UTF_8);
        System.out.println("UDP "+ response +System.currentTimeMillis());
        ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8), msg.sender()));
    }
}

public void sendPackage() {
    EventLoopGroup group = new NioEventLoopGroup();
    try {
        Bootstrap b = new Bootstrap();
        b.group(group).channel(NioDatagramChannel.class).option(ChannelOption.SO_BROADCAST, true)
                .handler(new ClientHandler());

        Channel ch = b.bind(0).sync().channel();

        ch.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("hello!!!", CharsetUtil.UTF_8),
                new InetSocketAddress("255.255.255.255", scanPort))).sync();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        group.shutdownGracefully();
    }
}

public static void main(String args[]) {
    Client client = new Client(AppConstants.SEARCH_PORT);
    client.sendPackage();
}

}

public class AppConstants {

public static final int SEARCH_PORT = 22023;

}

beykery commented 6 years ago

这个地方是因为update的时候并没有真的发出去,send后需要等到10ms以后才发。 现在还没有想好怎么改。

tidus5 commented 6 years ago

@beykery 那么可否这样理解: send 的时候,可以把list 里堆积的消息全部发出去么。 就算更新频率慢些,但发送消息条数应该不会差太多才对。另外更新频率参数我试着修改到 1ms, 数量还是没有明显提高。

beykery commented 6 years ago

你改成1ms是没用的,因为最小就是10ms; 另外,send的时候会先保存到queue里面,等下一个调度,10ms后才能发出去,那么,对端也就是10ms以后才能收到,收到后echo回去,还是要等10ms才能真正发出去;这就是为何你的测试echo的时候很慢。 但我还没想好怎么改。

tidus5 commented 6 years ago

noDelay(int nodelay, int interval, int resend, int nc) 这个方法的的 interval 参数,是否就算这个调度时长? 我是把这个参数。。。额,看到内部代码了,包内部最小设置了是10ms。 那么,C#的原版的代码是否也有这个问题呢,就是互发频率不够高的问题?

beykery commented 6 years ago

你说的哪个c#原版?

tidus5 commented 6 years ago

https://github.com/skywind3000/kcp

这个啊,kcp的原版。 哦,原版是C++的,记错了

beykery commented 6 years ago

这个问题,可以参考原作的这个issue: https://github.com/skywind3000/kcp/issues/105 看来也没有特别的办法了。