java - 关闭扫描仪导致无限循环

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

}

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

最佳答案

无需删除reader.close(),只需在主方法中创建扫描仪实例并将该实例传递给askPort()方法即可。

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

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

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

关于java - 关闭扫描仪导致无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49095022/

相关文章:

java - SQlite 查询 DateTime 中的不同日期

java - 日期选择器无法在文本框上正常工作

java - 双倍计算错误

java - 如果用户为 Scanner 的 next() 输入两个单词,第二个单词将被传输到随后的 nextInt() 方法,从而导致 inputMismatchException

java - 查找 Java 服务器时间和客户端时间

java - 覆盖 ClassNames 函数而不创建扩展 ClassName 的新类

java - 当字符串变量的输入前面有整数输入时,该输入将被跳过

java - 程序绕过多个条件的 while 循环 (java)

java - DataInputStream 给出 java.io.EOFException

sockets - TCP监听器和套接字之间的区别