【问题标题】:Java TCP communication through Socket通过 Socket 进行 Java TCP 通信
【发布时间】:2013-11-10 02:01:37
【问题描述】:

我正在尝试使用 TCP 通过套接字进行通信。需要发送的数据是一个绘图,而它正在被绘制。所以可以选择发送所有点,或者只发送形状(点系列)。

既然立即绘制它会很好,发送点似乎更好。它仅供本地使用,因此大量数据不应该成为问题。现在我遇到的问题是了解套接字的工作原理。目前我的代码如下:

    while(true){

        try {
            Thread.sleep(10);
         }
         catch (InterruptedException e) {}

        switch(connectionStatus){
        case CONNECTED:
            if(isHost){
                try {
                    oos.writeObject(myObject);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else{
                try {
                    myObject = (myObjectType) ois.readObject();
                    mainFrame.repaint();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            break;
      }
}

但不用说,这似乎相当低效,因为它一直在运行。当有新数据时,有没有办法只写入ObjectOutputStream (oos)?我想要阅读,您必须进行民意调查。读取是否也会清除 ObjectOutputStream?

编辑

要明确:我想通过套接字发送多个Point-objects。因此,每次将Point 添加到例如服务器时,它都应该将此点发送给客户端。

现在,我需要在oos.writeObject() 中添加什么?单个Point,还是Points 的List?以及它们是如何从ois.readObject() 中检索到的?

我有点困惑,因为写入 ObjectOutputStream 可能快也可能慢。 Se 读取 ObjectInputStream - 我看到它的方式 - 会或导致很大的延迟(如果它每 ~ 15 毫秒读取一个值并且点的添加速度比这更快)或导致很多延迟。

【问题讨论】:

    标签: java sockets tcp


    【解决方案1】:

    有没有办法只在有新数据时写入ObjectOutputStream (oos)?

    是的。每当用户画东西时,将数据推送到ObjectInputStream

    我猜想阅读你必须投票。

    这是不正确的。通常,从打开的流中读取是一个阻塞操作:如果您尝试读取某些内容但那里没有任何内容,read 方法将简单地阻塞,直到有新数据可用。

    【讨论】:

    • 所以如果我理解正确,例如当一个新的Point 被添加时,我只需使用oos.writeObject(new Point(20, 20))Point 推送到ObjectOutputStream 上?如果在接收者拥有read 之前已将多个点写入oos,会发生什么情况?
    • 假设您正在正确处理多线程(如果您的程序中有任何多线程),那么是的,您只需将对象推送到流中。如果已写入多个点(串行!您必须按顺序将对象写入流,而不是并行),一旦接收器开始读取它们,它们将按顺序读取。同时,数据会累积在发送方和接收方之间的缓冲区中;这是由 TCP/IP 堆栈实现的,通常您不必担心它。
    • 不确定多线程部分......它只是从一个“程序”到另一个,所以我认为我不需要它。尽管如此,我只是根据发件人的意愿将Points 推到ObjectOutputStream,并使用上面的while(true)-part 读取ObjectInputStream,它似乎有效!虽然我没有使用 Points,但我创建了一个提供线的起点和终点的类。所以现在我已经解决了,它似乎可以毫无延迟地工作,谢谢!
    【解决方案2】:
    1. 对于写入,您需要采用线程和同步技术,以便仅在数据可用时写入。一个线程通知新数据可用,另一个线程等待并收到通知并在被告知数据已到达时继续执行;
    2. 读取不会清除 ObjectOutputStream。事实上,您可以使用两个线程同时处理输入和输出流。
    3. 读取对象是一个同步操作,这意味着您的线程会一直等待,直到对象准备好。

    【讨论】:

      【解决方案3】:

      我写了一个库(你可以在 maven 上找到),它可以消除你自己实现线程和同步的一些复杂性:

      https://github.com/xtrinch/socket-live

      由三个主要组件组成(后来形成三个运行线程):

      SocketConnection.java:主线程,由库的用户运行,确保连接始终打开

      SocketRead.java:读取线程不断尝试读取传入消息(如果有)

      SocketWrite.java: 将写入队列中的任何消息写入套接字的写入线程

      如果不需要,您还可以选择禁用读取线程。

      库将确保连接始终保持打开状态,关闭后重新连接,并且已经过实战测试:)

      【讨论】:

        猜你喜欢
        • 2015-05-24
        • 2014-11-05
        • 2014-05-28
        • 1970-01-01
        • 1970-01-01
        • 2017-11-09
        • 2021-07-29
        • 2018-06-28
        • 1970-01-01
        相关资源
        最近更新 更多