【问题标题】:Declaring input/output streams from socket preventing program from continuing从套接字声明输入/输出流阻止程序继续
【发布时间】:2015-02-12 02:32:53
【问题描述】:

好的,所以我已经编写了一个使用服务器的简单通信程序,实际上作为一个测试比其他任何东西都重要,所以我知道它缺少很多,但是使用以下客户端类:

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 Streams 的位置时简单地停止。该程序没有退出,它似乎没有进入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;
        }
    }

}

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

【问题讨论】:

  • 只是提示:打印“所有声明”的那一行上方的两行没有声明任何内容。
  • 你怎么知道它没有卡在new Socket(server, port)
  • @immibis 正确,但将输出更改为“全部分配”。不会真正使代码运行得更好。
  • @immibis 我已将其删除,因为我已经从该行中找出了我需要的内容,但我在new Socket(server, port) 之后添加了一行以立即将某些内容输出到控制台,并且它正确打印每次我运行它时都到控制台,所以我很确定这不是问题。

标签: java sockets io objectinputstream objectoutputstream


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2013-10-11
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2012-08-16
    相关资源
    最近更新 更多