当前位置: 首页 > 知识库问答 >
问题:

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

赫连晋
2023-03-14

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

但是,我最终在客户端为每个连接创建了一个新线程,这导致了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从客户端创建多个连接,而不必为每个客户端生成新线程。我在另一篇关于堆栈溢出的文章中尝试了一个也是唯一一个针对类似情况的代码片段,但对于我来说,在第一次成功连接之后,执行暂停(进入无限等待状态)。

谢谢

共有1个答案

全宪
2023-03-14

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

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

对于异步aproach,请避免connect()future上的sync()(不太重要)以及close()future上的sync()。后者将暂停代码,直到连接关闭。

 类似资料:
  • 我正在使用Netty4创建一个需要为多个客户端连接提供服务的服务器。ServerBootstrap由父线程组和工作线程组构成。根据ServerBootStrap上的文档。group()方法it “为父(接收器)和子(客户端)设置EventLoopGroup。这些EventLoopGroup用于处理SocketChannel和Channel的所有事件和IO。” 据我所知,ParentExecutor

  • 我正在尝试连接到MBean服务器。我需要编写JMX客户端应用程序。这是用于客户端应用程序的代码。但我有一个例外 检索RMIServer存根失败:javax.naming.ServiceUnavailableException[根异常为java.rmi.ConnectException:连接拒绝主机:localhost;嵌套异常为: 谁能帮我把这个修好。 我使用以下参数运行了这段代码。 dcom.s

  • 创建客户端有两种方式,一种是直接使用特化的构造器函数,另一种是使用工厂构造器函数。 第一种方式返回的是具体的客户端结构体指针对象,第二种方式返回的是客户端接口对象。 使用特化的构造器函数创建客户端 特化的构造器函数有下面几个: func NewHTTPClient(uri ...string) (client *HTTPClient) func NewTCPClient(uri ...string

  • 我使用这个(Android TCP连接增强的)教程来创建简单的JAVA TCPServer和Android TCPClient。它工作得很好,但使用这段代码我只能同时将一个设备连接到服务器。我必须更改什么才能连接多个设备?

  • 问题内容: RMI是否自己处理多个客户端?即 是否可以同时使用多个客户端的服务器功能? 如果没有,我该怎么做? 如果是,它如何工作?每次 调用 都会创建一个新线程吗?如果一个客户端阻止了该功能,那么下一个客户端会发生什么?等等 问题答案: 是 这个怎么运作?每次调用都会创建一个新线程吗?如果一个客户端阻止了该功能,那么下一个客户端会发生什么?等等 它为每个客户端连接创建一个线程。 如果一个客户端调

  • 问题内容: 我正在开发多人游戏,无法找出如何将其他客户端连接到所创建的游戏。我的意思是客户端A创建与服务器的套接字连接,其他客户端(A,B …)如何连接到客户端A?有人可以帮我吗? PS我是网络编程的新手,因此,如果您可以举一些例子,我将不胜感激。 问题答案: 另一个客户端由于其防火墙而无法连接到客户端A。 您可以创建两种主要的网络: 服务器客户端 点对点 但是客户端可以将一些数据保存到服务器,服