关闭扫描仪会导致无限循环

时间:2018-03-04 11:45:40

标签: java java.util.scanner serversocket

我从Java套接字开始并尝试向用户询问服务器端口。 如果端口已经在使用中,我会再次询问。

一旦我问了两次,读者就会烦恼并产生一个无限循环。 删除reader.close()解决了我的问题,但我想了解发生了什么。

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;
    }

}

要测试问题,只需运行2倍代码并选择相同的端口。

2 个答案:

答案 0 :(得分:1)

不是删除reader.close(),而是在main方法中创建scanner实例,并将实例传递给askPort()方法。

在catch语句之后在main方法中有一个finally块,并关闭finally块中的reader。

此外,JAVA 7引入了自动资源管理,一旦try块的执行完成,try块内定义的资源将自动关闭。

只需检查一次是否自动关闭try块中定义的reader资源,您也无需处理关闭该资源...

答案 1 :(得分:0)

关闭扫描程序会关闭底层的InputStream,即System.in。一旦你关闭了System.in,它就关闭了,你再也看不懂了。 @JB Nizet