Singleton网络对象在第二次调用时出错

时间:2015-03-28 19:14:31

标签: java network-programming singleton

将创建单例对象的通信类:

import java.net.*;
import java.io.*;
import java.util.Scanner;

public class Communication {

    private static Communication mInstance = null;

    private static final String REQUEST_LOGIN = "Login";    

    private BufferedOutputStream socketOutput = null;
    private PrintWriter printOut = null;
    private Socket socket = null;
    private Scanner reader = null;  

    private Communication()
    {
        //connect to server using loopback address
        try{
            socket = new Socket("127.0.0.1", 4242);
            //set inputs and out puts
            socketOutput = new BufferedOutputStream(socket.getOutputStream());
            printOut = new PrintWriter(socket.getOutputStream(), true);
            reader = new Scanner(socket.getInputStream());
        }
        catch( UnknownHostException uhe){
            uhe.printStackTrace();
        }
        catch( IOException ex){
            ex.printStackTrace();
        }
    }

   public static Communication getInstance(){
        if(mInstance == null)
        {
            mInstance = new Communication();
        }
        return mInstance;
    }   

    //sample method for requesting login
    public boolean login(String u, String p){       
        try{            
            String username = u;
            String password = p;                

            printOut.printf("%s!%s@%s\n", REQUEST_LOGIN, username, password);
            int loginStatus = reader.nextInt();
            if (loginStatus == 1){
                    socketOutput.close();
                    socket.close();                 
                    return true;}
            else{
                socketOutput.close();
                socket.close();             
                return false;
            }           
        }
        catch( IOException ex){
            ex.printStackTrace();
            return false;
        }
    }   
}

另一个将重复使用单例对象的类:

public class Go{
    public static void main(String[] args) {            
        Communication.getInstance().login("user", "password");
        Communication.getInstance().login("user", "password");
    }
}

第一次通话没问题,验证就发生了。第二次调用会调用错误:

Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:907)
    at java.util.Scanner.next(Scanner.java:1530)
    at java.util.Scanner.nextInt(Scanner.java:2160)
    at java.util.Scanner.nextInt(Scanner.java:2119)
    at Communication.login(Communication.java:49)
    at Go.main(Go.java:7)

如何重复使用该对象?

1 个答案:

答案 0 :(得分:1)

login方法关闭套接字,第二次调用时扫描程序在死输入流上工作。应用程序流中的某些内容已被破坏。

传播者是一个单身人士,你打破它,因为你在登录方法中使其所有资产无效。 getInstance()方法查找仍然设置的单例(因为您没有在登录结束时设置单例null)并返回死对象。

然后,scanner尝试在已关闭的套接字输入流上尝试readInt。我认为这不应该有用。