从套接字声明输入/输出流阻止程序继续

时间:2015-02-12 02:32:54

标签: java sockets io objectinputstream objectoutputstream

好吧,所以我已经使用服务器编写了一个简单的通信程序,实际上作为一个测试而不是其他任何东西,所以我知道它遗失了很多,但有以下几点客户类:

public class Client {
    private ObjectInputStream in;
    private ObjectOutputStream out;

    private Socket socket;

    private String server;
    private int port;

    public Client(String ip, int p){
        port = p;
        server = ip;
    }

    public boolean start(){
        try{
            socket = new Socket(server, port);
        }catch(Exception e){
            System.out.println("Exception");
            e.printStackTrace();
            return false;
        }
        try{
            in = new ObjectInputStream(socket.getInputStream());
            out = new ObjectOutputStream(socket.getOutputStream());
            System.out.println("All declared");
        }catch(Exception e){
            System.out.println("Exception");
            e.printStackTrace();
            return false;}
        new LThread().start();
        return true;
    }

    private void sendMessage(Message msg){
        try{
        out.writeObject(msg);
        }catch(Exception e){}
    }

    public static void main(String[] args){
        int portNum = 1500;
        String servers = "localhost";

        Client client = new Client(servers, portNum);

        System.out.println("Client started");

        if(!client.start()){
            System.out.println("Didn't work");
            return;
        }

        System.out.println("Client started again");


        Scanner scan = new Scanner(System.in);

        while(true){
            String i = scan.nextLine();
            client.sendMessage(new Message(2, i));
        }
    }

    class LThread extends Thread{

        public void run(){
            System.out.println("Lthread running");
            while(true){
                try{
                    String message = (String)in.readObject();
                    System.out.println(message);
                }catch(Exception e){
                    e.printStackTrace();}
            }
        }

    }
}

程序在到达声明ObjectInputOutput Stream s的点时停止。该程序没有退出,它似乎没有进入catch块,我根本无法弄清楚究竟是什么原因造成它。该行"全部声明。"从不打印,但打印之前的任何内容。有谁能告诉我为什么我的程序在此时停止运行而不显示任何错误?

编辑:我认为我的服务器文件中可能存在错误,所以这里是类:

public class Server {

    private static int uid;

    private ArrayList<ClientThread> clients;
    private int port;
    private boolean cont;

    public Server(int p){
        port = p;
        clients = new ArrayList<ClientThread>();
    }

    public void start(){
        System.out.println("Started");
        cont = true;
        try{
            ServerSocket srvr = new ServerSocket(port);
            System.out.println("Declared socket");
            while(cont){
                Socket sk = srvr.accept();
                System.out.println("Socket accepted");

                if(!cont)break;

                ClientThread t = new ClientThread(sk);
                clients.add(t);
                t.start();
            }
            try{
                srvr.close();
                for(ClientThread t : clients){
                    t.in.close();
                    t.out.close();
                    t.socket.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }catch(Exception e){

            e.printStackTrace();
        }
    }

    private synchronized void broadcast(String msg){
        for(int i=clients.size(); --i >= 0;){
            ClientThread t= clients.get(i);
                if(!t.writeMsg(msg)){
                    clients.remove(i);
                }
        }
    }

    public static void main(String[] args){
        int portNum = 1500;

        Server server = new Server(portNum);
        server.start();
    }

    class ClientThread extends Thread{
        Socket socket;
        ObjectInputStream in;
        ObjectOutputStream out;
        String name;
        int id;
        Message m;

        ClientThread(Socket s){
            id = ++uid;
            socket = s;
            try{
                System.out.println("Before");
                in = new ObjectInputStream(socket.getInputStream());
                out = new ObjectOutputStream(socket.getOutputStream());
                System.out.println("After");
            }catch(Exception e){
                e.printStackTrace();}
        }

        public void run(){
            boolean c = true;
            while(c){
                try{
                    m = (Message)in.readObject();
                    switch(m.getType()){
                    case 2:
                        broadcast(m.getMessage());
                    }
                }catch (Exception e){
                    e.printStackTrace();}
            }
        }

        public boolean writeMsg(String msg){
            if(!socket.isConnected()){
                return false;
            }
            try{
                out.writeObject(msg);
            }catch(Exception e){
                e.printStackTrace();}
            return true;
        }
    }

}

好的,另一个编辑。所以我将这两个println添加到try构造函数中的ClientThread语句中,就像客户端一样,它运行直到我尝试初始化流,并且然后它就停止了。再一次,没有错误,没有任何东西;它完全停在轨道上。我无法弄清楚为什么会发生这种情况,但如果它意味着什么,我会使用Eclipse IDE来运行它。

1 个答案:

答案 0 :(得分:1)

第一次使用 ObjectInputStream ObjectOutputStream 时,我抓住了这个问题。问题的根本原因在于constructor ObjectInputStream。构造函数将从底层流中读取,以尝试获取标题信息,例如有线格式版本。

为了防止客户端和服务器无限等待对方先发送信息,您应该反转输入和输出流的顺序,然后显式刷新输出流。以下在客户端和服务器中构建流将解决您的问题:

out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = new ObjectInputStream(socket.getInputStream());