有可能错过连接吗?

时间:2015-07-28 19:07:16

标签: java multithreading sockets

我正在编写一个简单的异步tcp服务器&客户端程序,我很好奇,如果方法" waitForConnections"错过了连接,因为它仍然忙于接受新连接或开始收听它。

我测试了250个客户端,但我没有注意到连接丢失。

我用于测试的代码:

  for(int counter = 0; 250 > counter; counter++)
        {
            final int localCounter = counter;

            new Thread(() -> {
                try {
                    Socket socket = new Socket(ip, port);

                    System.out.println("Connected!");

                    DataOutputStream out =
                            new DataOutputStream(socket.getOutputStream());

                    out.writeUTF("#" + localCounter + " hello server!");

                    listenToConnection(socket);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }

服务器代码:

public class Server extends Thread {

private ServerSocket serverSocket;
private final Integer port;
private int amountConnections = 0;

public Server(Integer port) {
    this.port = port;
}

public void run() {
    startServer(port);
}

private void startServer(Integer port) {
    System.out.println("Server started!");
    try {
        serverSocket = new ServerSocket(port);
        waitForConnections();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void waitForConnections() {
    try {
        Socket socket = serverSocket.accept();
        System.out.println("New connection from: " + socket.getRemoteSocketAddress()  + " - amount connections: " + amountConnections);
        amountConnections++;
        asyncListenToConnection(socket);
    } catch (IOException e) {
        e.printStackTrace();
    }
    finally{
        waitForConnections();
    }
}

// Creates a new thread for each connection to listen to
private void asyncListenToConnection(Socket socket) {
    new Thread(() -> {
        while (!socket.isClosed()) {
            try {
                DataInputStream in =
                        new DataInputStream(socket.getInputStream());

                System.out.println("Connection: " + socket.getRemoteSocketAddress() + " says: " + in.readUTF());
            } catch (IOException e) {
                closeConnection(socket);
            }
        }
    }).start();
}

private void closeConnection(Socket socket) {
    if (!socket.isClosed() || socket.isConnected()) {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Connection: " + socket.getRemoteSocketAddress() + " has left");
        }
    }
}

我是Java,线程和套接字的新手,所以欢迎任何提示,包括改进代码。

1 个答案:

答案 0 :(得分:0)

因为你打电话

serverSocket = new ServerSocket(port);

没有backlog参数,根据Oracle Documentation for ServerSocket:

http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

  

传入连接指示的最大队列长度(a   请求连接)设置为50.如果连接指示到达   当队列已满时,连接被拒绝。

您可以通过增加积压来减少这种可能性。如果您还编写了客户端代码,则可以让客户端在连接被拒绝后自动重试。