Netty 4从客户端创建多个连接

时间:2015-10-15 14:45:15

标签: java linux multithreading netty nio

我正在尝试从另一台机器创建与基于java的套接字服务器的多个客户端连接。服务器和客户端都使用Netty 4 for NIO。在服务器端,我使用了boss和worker组,并且能够在单个linux机器上接收和服务器100000并发连接(在设置内核参数和ulimit之后)。

但是,我最终在客户端为每个连接创建一个新线程,并导致JVM线程限制异常。

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
​
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
​
public class TelnetClient
{
    private Bootstrap b;
    private NioEventLoopGroup loopGroup;
    private TelnetConnectionInitializer tci;
​
​
    public static void main(String[] args) throws Exception
    {
        System.out.println("TelnetClient:main:enter " + args[0]);
​
        TelnetClient tc = new TelnetClient();
​
        String countStr = args[0];  //number of connections to make
        int count = Integer.valueOf(countStr);
​
        for (int i=0; i < count; i++)
        {
            params.add(String.valueOf(i));
            Runnable r = new ClientThread(tc);
            new Thread(r).start();
        }
​
        System.out.println("TelnetClient:main:exit");
    }
​
    public TelnetClient()
    {
        System.out.println("TelnetClient:TelnetClient");
        b = new Bootstrap();
        loopGroup = new NioEventLoopGroup();
        b = b.group(loopGroup);
        b = b.channel(NioSocketChannel.class);
        tci = new TelnetConnectionInitializer();
    }
​
    public void connect(String host, int port) throws Exception {
        System.out.println("TelnetClient:connect:enter");
​
        try {
            b.handler(tci).connect(host, port).sync().channel().closeFuture().sync();
        } finally {
            b.group().shutdownGracefully();
        }
        System.out.println("TelnetClient:connect:exit");
    }
}
​
/// Creating a new thread per connection, 
/// Which seems the culprit of JVM exception, but couldn't found a way to implement boss / worker like solution on client side. 
class ClientThread implements Runnable
{
    TelnetClient myTc;
​
    public ClientThread(TelnetClient tc)
    {
        myTc = tc;
    }
​
    public void run()
    {
        System.out.println("ClientThread:run");    ​
        try
        {
            myTc.connect("192.168.1.65", 4598);  //Server running on different machine in local network
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

有人能指出我,如何使用Netty从客户端创建多个连接,而不会为每个客户端生成新线程。我在another post on stack overflow中尝试了一个且只有类似条件的片段,但是在那之后,我首次成功连接后暂停执行(进入无限等待状态)。

由于

1 个答案:

答案 0 :(得分:0)

除了两个重要的事情之外,代码看起来是正确的 - 您必须由所有客户端共享netty上下文并异步工作。

即。在开头初始化EvenetLoopGroup,并将此单个实例传递给每个客户端的每次Bootstrap.group()调用。

对于异步aproach,避免在connect()未来(不是那么重要)和主要在close()未来的sync()。后者代码被暂停,直到连接关闭。