【问题标题】:How to pass sockets created to another Java Process如何将创建的套接字传递给另一个 Java 进程
【发布时间】:2010-12-27 16:27:46
【问题描述】:

我们有一个应用程序创建了许多属于它的线程的套接字,按照设计,如果这个应用程序以某种方式失败,所有线程都会停止,这是不想要的。所以要克服这个问题,每个线程必须与主应用程序分离,如果一个线程失败,其他线程应该运行。我们想到的一件事是将创建的socket传递给另一个java进程,那么正确的方法是什么?

也欢迎使用其他方法?

等待您的建议...

【问题讨论】:

    标签: java multithreading sockets


    【解决方案1】:

    分叉:

    据我所知,您不能使用普通 API 在 Java 进程之间传递套接字句柄。但是,它似乎在 Windows using the Winsock 2 API 上是可能的。在 Posix 上,您应该能够派生一个可以访问父套接字的子进程,因为 forked processes inherit the parent's sockets

    我认为,您可以实现一个新的 SocketImpl 类,该类支持将套接字句柄移动到另一个进程,但您需要编写一些 JNI 代码来执行此操作。

    对我来说听起来很麻烦,我怀疑从 Java 中分叉一个新进程是个好主意!

    听众:

    另一种方法可能是生成一个新的“侦听器”进程,该进程本质上是一个新的预分叉工作者。然后每个工作人员可以轮流监听套接字的连接。 然后,工作人员将需要与一个控制进程进行协调,该进程根据需要管理生成新进程。

    我同意@Bozho,如果一个线程中的错误可以让它们全部崩溃(我想它必须是一个 JVM 异常杀死整个应用程序)你有一个更大的问题。如果可能,您应该考虑隔离线程。

    【讨论】:

      【解决方案2】:

      不是。 (套接字不能被序列化。)

      当一个线程失败时,它的异常应该被捕获、记录下来,并且这不应该干扰其他线程。 所以要么设计让它完全停止,要么设计成完全停止。

      或者将关于套接字(地址/端口)的所有信息传递给另一个应用程序,该应用程序本身可以打开一个类似的套接字。

      【讨论】:

      • @Bozho - 所以你的意思是套接字被锁定到它的进程,世界上没有这样的事情吗?
      • 在 java 之外您可以传递套接字,但 java API 不支持它。这意味着您必须编写 JNI 代码才能在 JVM 中支持这一点。
      【解决方案3】:

      看到这个类似的问题socket passing between processes
      不幸的是,地址空间的障碍不能被超越。

      【讨论】:

        【解决方案4】:

        我更同意 Bozho 的观点,您需要重新设计您的应用程序/评论线程,以便异常或错误会杀死您的整个 VM。

        为了帮助你,我建议你看看:

        • Thread.setDefaultUncaughtExceptionHandler(...) 和 Thread.setUncaughtExceptionHandler(...) (参见下面的超链接) 这有助于获取无法预见的问题(例如运行时)
        • Runtime.addShutdownHook(...) (参见下面的超链接) 这有助于很好地关闭事物(例如当发生 OutOfMemoryError 时)

        问候

        Cerber

        http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)

        【讨论】:

          【解决方案5】:

          使用线程之间共享的类来保存套接字。您可以使用 HashMap 标记每个套接字,以便其他线程可以引用它需要的那个。

          【讨论】:

          • 通常我使用一个实现单例模式的类来做这种事情。
          • 我的意思是模式^
          【解决方案6】:

          我想回应那些说“只捕获异常并退出线程”的人。

          您无法捕获所有异常。以下导致 java jvm 退出:

          • 由于 jvm 实现中的错误而断言 jvm
          • jni 代码(sigsegv、sigabrt)中的一些故障
          • 内存不足

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-01-03
            • 2017-03-18
            • 2013-05-09
            • 2013-12-16
            • 2011-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多