【问题标题】:Java socket: Pushing requests to client through socketJava套接字:通过套接字向客户端推送请求
【发布时间】:2012-10-27 06:59:41
【问题描述】:

我目前正在制作一个客户端-服务器应用程序,该应用程序主要用于对服务器进行过程调用并等待数据包响应。

但是我想让服务器将消息“推送”给客户端(在自发的时间),但是如果消息在客户端侦听另一个数据包响应时到达,这似乎是一个问题。

有没有办法通过同一个套接字实例将一个套接字拆分为 2 个唯一的通道流?或者创建一个只监听传入连接并将它们分派到队列的客户端线程会更好吗?

在使用 2 路客户端-服务器连接时,有哪些常见的模式和做法? (流自发产生的地方)

提醒一下,我正在使用 Java Socket、ObjectInputStream 和 ObjectOutputstream。我没有使用 Java RMI。

【问题讨论】:

  • 您应该提供一些代码。也许这只是一个简单的错误。

标签: java sockets networking tcp client-server


【解决方案1】:

因此,您在学习网络时会遇到的一件事就是失去同步。例如,当您“硬编码”一组客户端-服务器交互时,就会发生这种情况;

server sends 2 byte status code
client receives 2 byte status code
client responds with 4 byte operation code

如果由于某种原因有一个错误导致此交互的任何部分不能完全按照它的需要发生,那么程序的 rest 将失败,因为所有网络交互现在都不同步.客户端可能会读取它认为代表字符串的一组字节,而实际上服务器正在发送一个 int,等等。最糟糕的是,您可能会发现主网络线程死锁,因为客户端和服务器都在同时等待输入。

对于一个较大的项目,其中肯定存在错误,如果您以这种风格编写代码,这种情况发生很多。出于这个原因,我们有一个叫做middleware的东西。

一个非常常见且灵活的中间件范例是TLV Message Protocol。您将实现一些简单的类(在半 java 伪代码中);

TLVMessage
    int type;
    byte[] value;

TLVPusher implements Runnable
    OutputStream out;
    Queue<TLVMessage> messages;
    run() {
        while(true) {
            //poll and write front of queue to out (INCLUDING value.length!)
        }
    }

TLVReader implements Runnable
    InputStream in;
    Queue<TLVMessage> messages;
    run() {
        while(true) {
            //read message from in and add to queue
        }
    }

现在您有两个线程在客户端运行,两个线程在服务器上运行。每一端都有自己的PusherReader。需要注意的重要一点是,由于您将 length 字段写入输出流,读取器总是知道它需要读取多少字节。因此即使一条消息被错误地序列化,它的长度仍然是正确的,并且下一条消息总是会从第一个字节到最后一个字节被正确读取。这样您的程序就永远不会不同步。

您只需将TLVMessage 对象添加到pusher.queue,它们就会到达套接字另一端的reader.queue。然后,您可以通过它们的type 字段处理消息(在另一个,第三个,监视reader.messages.size() 的线程中)。

您无需担心事情发生的顺序,您有一个强大的机制在客户端和服务器之间在两个方向上传递消息。你已经把繁琐的网络东西抽象出来了,可以继续编码了。

当然,libraries 可以为您完成所有这些工作,但在我看来,了解 如何为什么 总是值得的。

【讨论】:

  • 如果“某些硬件/其他问题导致此交互的任何部分失败”,则整个连接会失败。毫无疑问只是“不同步”。
  • @EJP 是的,我将编辑该部分,谢谢。现在我只需要记住我想要表达的观点。
【解决方案2】:

您必须直接对套接字进行编码吗?听起来像是在OSI stack 中走高并使用例如的好人选。 JMS 实现你的目标。

希望对您有所帮助。

干杯,

【讨论】:

    猜你喜欢
    • 2011-08-26
    • 2018-09-08
    • 1970-01-01
    • 2015-04-28
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多