我有一个应用程序,它打开一个数据报套接字并发送到各种其他进程......有时这个应用程序启动另一个进程(使用 ProcessBuilder),它也进行一些网络通信......
现在,笑话是,启动的进程“有时”只会在主应用程序终止后接收消息......或者有时它会发送到 X,但它们只会在主应用程序停止时才被传递......
我不知道发生了什么……有人听说过这样的事情吗?仅在进程停止时传输数据包?
我一直在用 Java 中的套接字编程已经有一段时间了,但我确实记得你必须显式地刷新套接字才能“强制”发送所有数据。这将在为您关闭套接字时完成,这将解释您观察到的行为。
Is the child process writing to System.out
or System.err
? Have you set up the main process to drain those streams once the child process is started? It could be that the child process is just deadlocked trying to print a log message on a blocking stream that isn't being read. When the parent app is killed, the stream gets unblocked and everything starts moving again. It may be a longshot, but I've been bitten by it enough times when starting child processes that I always check.
你看过socket.setTcpNoDelay(true);
吗?
这是一种优化,它在通过网络发送数据之前等待收集一定数量的数据。对于发送零星和少量数据的应用程序,应将其设置为关闭。
编辑:对不起,我认为这仅适用于非数据报套接字。可能不是你的问题。
一种可能性是这是使用数据报的结果。数据报本质上是不可靠的,数据包可能会被丢弃或乱序传递。
您的应用程序也可能终止得太快。应用程序和启动的进程是否进行握手以确保它们都知道何时关闭?
编辑:
但实际上,我认为最可能的原因是子进程阻塞,因为父进程不读取写入子输出的内容......直到为时已晚。作为实验,将以下内容添加到子进程启动中:
OutputStream os = new FileOutputStream(...); // pick a suitable temp filename
System.setOut(os);
System.setErr(os);
如果这个 hack 解决了问题,那么肯定表明这是根本问题。