I'm starting with Java Sockets and trying to ask the user for the Server Port. If the port is already in use I ask it again.
As soon as I ask twice the reader is bugging and producing an infinite loop.
Removing the reader.close()
solve my problem but I would like to understand what is happening.
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Enumeration;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class ServerWithAskedPort {
public static void main(String[] args) {
ServerSocket mySkServer = null;
Socket srvSocket = null ;
InetAddress localAddress= null ;
String interfaceName = "lo";
boolean portOk = true;
try {
NetworkInterface ni = NetworkInterface.getByName(interfaceName);
Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
while(inetAddresses.hasMoreElements()) {
InetAddress ia = inetAddresses.nextElement();
if(!ia.isLinkLocalAddress() && !ia.getHostAddress().equals("0:0:0:0:0:0:0:1")) {
System.out.println(ni.getName() + "->IP: " + ia.getHostAddress());
localAddress = ia;
}
}
do {
portOk = true;
try {
mySkServer = new ServerSocket(askPort(),5,localAddress);
}
catch(BindException e) {
System.out.println("Error: port already in use");
portOk = false;
}
catch(NoSuchElementException e) {
portOk = false;
}
}while(!portOk);
System.out.println("Default Timeout :" + mySkServer.getSoTimeout());
System.out.println("Used IpAddress :" + mySkServer.getInetAddress());
System.out.println("Listening to Port :" + mySkServer.getLocalPort());
mySkServer.setSoTimeout(100000);//set 30 sec timout
//Listen to a client connection wait until a client connects
System.out.println("Waiting for a client connection:");
srvSocket = mySkServer.accept();
System.out.println("A client is connected");
mySkServer.close();
srvSocket.close();
System.out.println("Closing socket....");
}catch (SocketTimeoutException e) {
System.out.println("Connection Timed out");
}
catch (Exception e) {
e.printStackTrace();
}
}
public static int askPort() {
int portInt = 0;
boolean portOk;
Scanner reader = new Scanner(System.in);
do {
portOk = true;
System.out.println("Enter a port nummer : (1 ... 65535)");
try {
portInt = reader.nextInt();
if(portInt < 1 || portInt > 65535) {
System.out.println("Error: Port out of range");
portOk = false;
}
}
catch (InputMismatchException e) {
System.out.println("Erreur: Invalid format");
portOk = false;
}
}while(!portOk);
reader.close();
return portInt;
}
}
To test the issue just run 2x the code and select the same port.
Instead of removing reader.close()
, Just create the scanner instance in the main method and pass the instance to askPort() method.
Have a finally block in the main method after catch statements, and close the reader inside the finally block.
And moreover, JAVA 7 introduced Automatic Resource Management, where the resources defined inside the try block will be closed automatically once the execution of the try block is completed.
Just check once if it is closing the reader
resource defined inside try block automatically, you need not to handle closing that resource also...