许多同时连接期间Java套接字意外关闭

时间:2015-11-10 10:19:49

标签: java sockets tcp

我正在构建客户端 - 服务器应用程序,但每当我尝试将许多套接字连接到服务器时,客户端报告套接字已关闭(在Socket对象的实例化期间)

我得到的例外是:java.net.SocketException: Socket closed

问题始终发生在正好套接字号4077.我将服务器的待办事项设置为20,000个。

运行OS X El Capitan 64位,Java 8.

客户

public class RunIOClient
{
    private ArrayList<Connection> connections;

    private int connectionCount = 10000;
    private int packetsPerConnection = 0;

    public RunIOClient() throws InterruptedException
    {
        connections = new ArrayList<>();

        for (int i = 0; i < connectionCount; i++)
        {
            connections.add(new Connection("localhost", 9000, i + 1));
            Thread.sleep(10);
        }

        Thread.sleep(1000);

        for (int i = 0; i < packetsPerConnection; i++)
        {
            for (Connection c : connections)
            {
                String msg = "Hello " + (i + 1) + " from client " + c.getNumber();
                System.out.println("SENDING: " + msg);
                c.getOut().println(msg);
                Thread.sleep(5);
            }
        }

        Thread.sleep(60000);
    }

    public static void main(String[] args) throws InterruptedException
    {
        new RunIOClient();
    }
}

Connection实体

public class Connection
{
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    private int number;

    public Connection(String hostname, int port, int number)
    {
        this.number = number;

        try
        {
            socket = new Socket(hostname, port); // exception occurs here
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);
            System.out.println("Socket " + number + " connected");
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public Socket getSocket()
    {
        return socket;
    }

    public BufferedReader getIn()
    {
        return in;
    }

    public PrintWriter getOut()
    {
        return out;
    }

    public int getNumber()
    {
        return number;
    }
}

完整的堆栈跟踪

java.net.SocketException: Socket closed
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at java.net.Socket.connect(Socket.java:538)
    at java.net.Socket.<init>(Socket.java:434)
    at java.net.Socket.<init>(Socket.java:211)
    at Connection.<init>(Connection.java:20)
    at RunIOClient.<init>(RunIOClient.java:16)
    at RunIOClient.main(RunIOClient.java:38)

2 个答案:

答案 0 :(得分:0)

好吧,似乎OS X在文件描述符及其限制方面做了一些时髦的东西。

我将项目移动到Ubuntu 15机器上,以下解决了这个问题:

  • 确保您是root
  • 在终端:ulimit -n 100000
  • 在终端:ulimit -Hn 100000

这解决了我的问题。但是,它只适用于root用户(我无法更改非root用户的限制)。

因此,部分问题已得到解决。

答案 1 :(得分:-1)

这是因为您的服务器只支持一个用户,请输入:

name_array[0] = name;

为每个客户端创建一个新线程,并将该连接传递给将包含所有服务器命令的服务器处理程序。