【问题标题】:Program won't continue after initializing input/output streams?初始化输入/输出流后程序不会继续?
【发布时间】:2013-10-11 10:08:41
【问题描述】:

在人们怀疑我根本不知道自己在做什么(最终无缘无故地投票否决)之前,请阅读以下内容:

它可以很好地连接到我的服务器!我没有收到任何错误(来自客户端或服务器),并且我的服务器正在识别连接。它适用于他制作的我朋友的客户,但我想制作自己的客户,显然我做错了什么。请保持话题!谢谢:)


标题基本上说明了一切。我已经在我的 Client.java run() 中使用 setupStream() 上方和下方的 println 消息进行了测试,但仅打印了 setupStream() 上方的消息。我不确定我应该如何在不让程序停止的情况下初始化我的流。

客户端.java

import java.io.IOException;


public class Client extends Stream implements Runnable {
    public boolean running = false;
    private Thread clientThread;

    Frame frame;
    public Client() {
        super("localhost", 43594);

        frame = new ClientFrame(500, 500);
        start();
    }

    public synchronized void start() {
        if(running) return;
        running = true;

        clientThread = new Thread(this);
        clientThread.start();
    }
    public synchronized void stop() {
        if(!running) return;
        running = false;

        clientThread.interrupt();
        try {
            clientThread.join();
        } catch (InterruptedException e) {e.printStackTrace();}
    }

    public void run() {
        try{
        setupStream();

        while(running) {
            System.out.println("running");
        }
        }catch(IOException e) {
            e.printStackTrace();
        }finally {
            try{
            out.close();
            in.close();
            socket.close();
            clientThread.join();
            }catch(IOException | InterruptedException e) { e.printStackTrace(); }
        }
    }
    public static void main(String[] args) {
        new Client();
    }
}

Stream.java

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;


public class Stream {

    Socket socket;
    ObjectOutputStream out;
    ObjectInputStream in;
    String data;

    public Stream(String host, int port) {
        try {
            socket = new Socket(host, port);
        } catch (IOException e) { 
            e.printStackTrace();
        }
    }

    protected void setupStream() throws IOException {
        out = new ObjectOutputStream(socket.getOutputStream());
        out.flush();
        in = new ObjectInputStream(socket.getInputStream());
    }

}

我的服务器线程:

package Server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

public class User extends Thread {
    public static int users = 0;
    public int ID;
    public String username;
    boolean online = false;

    public static ArrayList<String> usernames = new ArrayList<String>();

    Socket socket;

    DataOutputStream out;
    DataInputStream in;
    String input;

    public User(Socket socket) {
        this.socket = socket;

    }

    public String decode(String input) {
        String[] split = input.split(" ");

        if(input.startsWith("::")) {
            try {
                switch(split[0].substring(2, split[0].length()).toLowerCase()) {
                case "setname": 
                case "changename":
                case "newname":
                    if(usernames.contains(split[1].toLowerCase())) {
                        out.writeUTF("This name is already taken! Please choose a different one.");
                        out.flush();
                        return null;
                    }
                    if(username == null) {
                        username = split[1].substring(0, 1).toUpperCase() + split[1].substring(1, split[1].length());
                        Server.users.put(split[1].toLowerCase(), Server.user[ID]);
                        usernames.add(split[1].toLowerCase());
                    } else {
                        usernames.remove(username.toLowerCase());
                        username = split[1].substring(0, 1).toUpperCase() + split[1].substring(1, split[1].length());
                        usernames.add(split[1].toLowerCase());
                    }
                        return null;
                case "rank+":
                    return null;
                case "[sm]=":
                    return null;
                }
            }catch(IOException e) { }
        }
        return input;
    }

    String timeStamp;
    public void run() {
        try {

            out = new DataOutputStream(socket.getOutputStream());
            out.flush();
            in = new DataInputStream(socket.getInputStream());

            while((input = in.readUTF()) != null) {
                input = decode(input);

                if(input != null) {
                    if(username != null) {
                        timeStamp = new SimpleDateFormat("[h:mm:ss] ").format(Calendar.getInstance().getTime());
                        Server.sendGlobalMessage(timeStamp + username +": "+input);
                    } else {
                        timeStamp = new SimpleDateFormat("[h:mm:ss] ").format(Calendar.getInstance().getTime());
                        Server.sendGlobalMessage(timeStamp + "Guest "+ID+": "+input);
                    }
                }
            }

        }catch(IOException e) { e.printStackTrace(); } finally { 
            try{
                out.close();
                in.close();
                socket.close();
            } catch(IOException e) { e.printStackTrace(); }
        }

    }

}

我已经有一段时间没有碰过我的服务器线程的代码了,因为在我创建新客户端之前它一直都在工作。

【问题讨论】:

  • 你默默地忽略了来自setupStream() 的异常。在 catch 块中至少添加 e.printStackTrace()
  • @VinceEmigh 你应该担心错误处理,Stream 构造函数总是失败,但由于异常被抑制,所以没有注意到。由于null Socket 进一步setupStream 抛出NPE,因为没有任何东西在听!
  • 没有太多方法不能到达setupStreams() 下面的行(锁定,或者抛出异常)。如果您从不检查异常,您怎么知道不会引发异常?您说您没有收到任何错误,但您粘贴的代码无法检测到。
  • 如果你省略那些堆栈跟踪,人们怎么可能知道你已经知道没有错误?您一开始并没有谈论服务器,因此您似乎忘记了它并且由于缺少堆栈跟踪而没有意识到...

标签: java sockets data-structures stream


【解决方案1】:

我怀疑你的服务器没有创建 ObjectOutputStream,所以当客户端构造它的 ObjectInputStream 时,它会阻塞等待永远不会到达的对象流标头。

【讨论】:

  • 正如我所说。 ObjectInputStream 在另一端需要一个 ObjectOutputStream,反之亦然。 但是关于异常处理的说明不容忽视。它不是您在程序运行后添加到程序中的东西。这是让它首先工作的重要部分。
猜你喜欢
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
相关资源
最近更新 更多