我正在编写一个简单的异步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,线程和套接字的新手,所以欢迎任何提示,包括改进代码。
答案 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.如果连接指示到达 当队列已满时,连接被拒绝。
您可以通过增加积压来减少这种可能性。如果您还编写了客户端代码,则可以让客户端在连接被拒绝后自动重试。