【问题标题】:Java Sockets sending multiple objects to the same serverJava Sockets 将多个对象发送到同一个服务器
【发布时间】:2016-08-02 18:30:15
【问题描述】:

我正在尝试通过套接字将多个对象发送到 java 服务器。

为了有一个通用类型,我将我的消息转换为 Message 类的一个实例并将这个对象发送到服务器。 我写了一个小测试类,它将三个对象发送到服务器。 问题是,只有一个对象到达服务器。 我几乎尝试了所有方法,但没有成功。

我的服务器:

public class Server {
    private ServerConfig conf = new ServerConfig();
    private int port = Integer.parseInt(conf.loadProp("ServerPort"));
    Logger log = new Logger();
    ServerSocket socket;
    Chat chat = new Chat();

    public static void main(String[] args) {
        Server s = new Server();
        if (s.runServer()) {
            s.listenToClients();
        }
    }

    public boolean runServer() {
        try {
            socket = new ServerSocket(port);
            logToConsole("Server wurde gestartet!");
            return true;
        } catch (IOException e) {
            logToConsole("Server konnte nicht gestartet werden!");
            e.printStackTrace();
            return false;
        }
    }

    public void listenToClients() {
        while (true) {
            try {
                Socket client = socket.accept();
                ObjectOutputStream writer = new ObjectOutputStream(client.getOutputStream());
                Thread clientThread = new Thread(new Handler(client, writer));
                clientThread.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void logToConsole(String message) {
        System.out.print(message);
    }

    public class Handler implements Runnable {

        Socket client;
        ObjectInputStream reader;
        ObjectOutputStream writer;
        User user;

        public Handler(Socket client, ObjectOutputStream writer) {
            try {
                this.client = client;
                this.writer = writer;
                this.reader = new ObjectInputStream(client.getInputStream());
                this.user = new User();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            while (true) {
                Message incomming;
                try {
                    while ((incomming = (Message) reader.readUnshared()) != null) {
                        logToConsole("Vom Client: \n" + reader.readObject().toString() + "\n");
                        logToConsole(
                                "Vom Client: \n" + incomming.getType() + "-----" + incomming.getValue().toString());
                        handle(incomming);
                    }
                } catch (SocketException se) {
                    se.printStackTrace();
                    Thread.currentThread().interrupt();

                } catch (IOException ioe) {
                    ioe.printStackTrace();
                    Thread.currentThread().interrupt();

                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();

                }

            }
        }

        private void handle(Message m) throws IOException {
            String type = m.getType();
            if (type.equals(config.ConstantList.Network.CHAT.toString())) {
                chat.sendMessage(m);
            } else if (type.equals(config.ConstantList.Network.LOGIN.toString())) {
                System.out.println(user.login(m.getValue().get(0), writer));
                System.out.println(m.getValue().get(0));
            }
        }
    }

}

客户:

public class Connect {

    Socket client = null;
    ObjectOutputStream writer = null;
    ObjectInputStream reader = null;
    private Config conf = new Config();
    //private String host = conf.loadProp("ServerIP");
    String  host = "localhost";
    private int port = Integer.parseInt(conf.loadProp("ServerPort"));

    public boolean connectToServer() {
        try {
            client = new Socket(host, port);
            reader = new ObjectInputStream(client.getInputStream());
            writer = new ObjectOutputStream(client.getOutputStream());
            logMessages("Netzwerkverbindung hergestellt");
            Thread t = new Thread(new MessagesFromServerListener());
            t.start();
            return true;
        } catch (Exception e) {
            logMessages("Netzwerkverbindung konnte nicht hergestellt werden");
            e.printStackTrace();
            return false;
        }
    }

    public boolean isConnectionActive() {
        if (client == null || writer == null || reader == null){
            return false;
        }else{
            return true;
        }
    }

    public void sendToServer(Message m) {
        try {
            writer.reset();
            writer.writeUnshared(m);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

我尝试用类发送对象:

public void sendChatMessage(String username, String message) throws InterruptedException {
        ChatMessage cm = new ChatMessage();
        cm.setChat(username, null, message);
        Message m = new Message(cm);
        conn.sendToServer(m);
        System.out.println("SENDED");
    }

public static void main(String[] args) throws InterruptedException {
        String username = "testuser";
        String chatmessage = "Hallo Welt!";
        connect.connect();
        sendChatMessage(username, chatmessage);
        sendChatMessage(username, chatmessage);
       sendChatMessage(username, chatmessage);
    }

我知道这始终是相同的消息,但仅用于测试目的。 消息是它们可序列化的对象,并且只有一个对象可以按设计工作。

有人能看出我在哪里犯错了吗?

【问题讨论】:

  • 在您希望读取第二个对象的处理程序中的服务器中添加一个断点。然后逐步查看源代码,看看发生了什么。
  • 我做到了,这里只显示一条消息,处理完成后,服务器处于空闲状态。

标签: java sockets object server


【解决方案1】:
while ((incomming = (Message) reader.readUnshared()) != null) {

这里你正在读取一个对象,并阻塞直到它到达。

    logToConsole("Vom Client: \n" + reader.readObject().toString() + "\n");

在这里,您正在读取 另一个 对象,并阻塞直到它到达,然后错误地将其记录为您在上一行中已经读取的对象。

您应该记录incoming 的值,而不是记录reader.readObject(),您也拼错了。

而且循环不正确。 readObject() 不会在流结束时返回 null:它会抛出 EOFException。任何时候你写 null 都可以返回 null,所以用它作为循环终止条件是完全错误的。你应该抓住EOFException 并休息一下。

【讨论】:

    【解决方案2】:

    找到解决方案,Server 类中的logToConsole("Vom Client: \n" + reader.readObject().toString() + "\n"); 行阻塞了连接。

    【讨论】:

      猜你喜欢
      • 2013-02-05
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 2012-05-16
      相关资源
      最近更新 更多