【问题标题】:Object In/Out stream. How to send updated, same object repeatedly and efficiently?对象输入/输出流。如何重复有效地发送更新的相同对象?
【发布时间】:2014-02-24 15:55:44
【问题描述】:

我在尝试使用 TCP 发送数据列表时遇到了一些麻烦。我把这个问题做了一个更小的版本,并稍微夸大了一点。

客户

public class Client {

    DListStorage dl = new DListStorage();
    Data d = new Data();

    Socket socket;

    public Client(){
        d.x = 0;
        dl.dl.add(d);

        try {
            socket = new Socket(InetAddress.getLocalHost(), port);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());

            for(int i = 0; i < 3; i++){
                oos.writeObject(dl);
                dl.dl.get(0).x++;
                System.out.println("Client: " + dl.dl.get(0).x);
            }

            socket.close();
            socket = new Socket(InetAddress.getLocalHost(), port);
            oos = new ObjectOutputStream(socket.getOutputStream());

            for(int i = 0; i < 3; i++){
                oos.writeObject(dl);
                dl.dl.get(0).x++;
                System.out.println("Client: " + dl.dl.get(0).x);
            }
        } catch (IOException e) {
                e.printStackTrace();
        }
    }
}

服务器

public class NewConnections {

    ServerSocket ssocket;
    Socket socket;

    public NewConnections(){
        acceptConnections.start();
    }

    Thread acceptConnections = new Thread(new Runnable(){
        public void run(){
            try {
                ssocket = new ServerSocket(port, 0, InetAddress.getLocalHost());
                socket = ssocket.accept();
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

                DListStorage dl;

                for(int i = 0; i < 3; i++){
                    dl = (DListStorage)ois.readObject();
                    System.out.println("Server: " + dl.dl.get(0).x);
                }

                socket.close();
                socket = ssocket.accept();
                ois = new ObjectInputStream(socket.getInputStream());

                for(int i = 0; i < 3; i++){
                    dl = (DListStorage)ois.readObject();
                    System.out.println("Server: " + dl.dl.get(0).x);
                }

                ssocket.close();
            } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
            }
        }
    });
}

我的结果如下。

Client: 0.0
Client: 1.0
Server: 0.0
Client: 2.0
Server: 0.0
Server: 0.0
Client: 3.0
Client: 4.0
Server: 3.0
Client: 5.0
Server: 3.0
Server: 3.0

Data 和 DataStorage 都实现了 Serializable,DataStorage 包含 public List&lt;Data&gt; dl = new ArrayList&lt;&gt;(); 我无法弄清楚为什么服务器没有正确读取 float x。仅在初次阅读时。

谢谢

【问题讨论】:

  • 我添加了oos.reset(),它正在工作,但我真的需要它尽可能高效。这不会导致大量开销,打开和关闭流吗?

标签: java list networking arraylist io


【解决方案1】:

试试:

服务器:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class NewConnections {

public NewConnections() {
    acceptConnections.start();
}

Thread acceptConnections = new Thread(new Runnable() {
    public void run() {
        try {
            int port = 81;
            ServerSocket ssocket = new ServerSocket(port, 0, InetAddress.getLocalHost());
            while (true) {
                System.out.println("waiting...");
                Socket socket = ssocket.accept();
                // buffered reader to read a line at a time from client
                BufferedReader ois = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));

                String x = null;
                // read till input is available from client
                while ((x = ois.readLine()) != null) {
                    System.out.println("Server: " + x);
                }
                ois.close();
                socket.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
}

客户:

import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class Client {

public Client() {
    int port = 81;
    int x = 0;
    try {

        Socket socket = new Socket(InetAddress.getLocalHost(), port);
        // use auto flush to send the data immediately to the server
        PrintWriter oos = new PrintWriter(socket.getOutputStream(), true);

        for (int i = 0; i < 3; i++) {
            x++;
            oos.println(x);
            System.out.println("Client: " + x);
        }
        oos.close();
        socket.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

【讨论】:

  • 在等待每行输入的无限循环中启动服务器线程。现在从客户端逐行发送数据,它将立即刷新到服务器。
  • 我会尽快回复您。我发现这个link 对重置输出流有很大帮助。它还提供了一些关于为什么会出现问题的见解。谢谢。
  • 抱歉,忙碌了这么久。我需要发送一个对象数组,否则我需要编写更多代码来解释每个单独的值(在数据类中)一个接一个地从客户端发送。数据包含大小、位置、布尔值和其他一些值。它适用于移动的精灵以及它发生的事情。需要告知服务器所有信息,以便以正确的方式处理精灵。关于其他选择的建议也很好。我希望通过互联网发送和接收数据
猜你喜欢
  • 2017-05-19
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 2012-12-19
  • 2020-11-17
  • 2014-07-22
相关资源
最近更新 更多