Gradle:MessageIOException:无法将消息 [EndOfStream] 写入 127.0.0.1(防火墙)?
Gradle: MessageIOException: Could not write message [EndOfStream] to 127.0.0.1 (Firewall)?
我写了一个简单的测试项目,打开9123
端口一段时间后退出:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Date;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class TimeServer
{
private static final int PORT = 9123;
public static void main( String[] args ) throws IOException
{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
acceptor.setHandler( new TimeServerHandler() );
acceptor.getSessionConfig().setReadBufferSize( 2048 );
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind( new InetSocketAddress(PORT) );
}
private static class TimeServerHandler extends IoHandlerAdapter {
@Override
public void exceptionCaught(IoSession session, Throwable cause ) throws Exception
{
cause.printStackTrace();
}
@Override
public void messageReceived( IoSession session, Object message ) throws Exception
{
String str = message.toString();
if( str.trim().equalsIgnoreCase("quit") ) {
session.close();
return;
}
Date date = new Date();
session.write( date.toString() );
System.out.println("Message written...");
}
@Override
public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
{
System.out.println( "IDLE " + session.getIdleCount( status ));
}
}
}
...
import java.io.IOException;
public class TimeServerTest {
@Test
public void runningTimeServerForTime() throws IOException, InterruptedException {
int period = 15000;
System.out.println("Running time server for " + period + "ms");
TimeServer.main(new String[] {});
Thread.sleep(period);
System.out.println("Done, exiting");
System.exit(0);
}
}
此测试 运行 在 IntelliJ 下正常并且 Windows 防火墙关闭时。
当 windows 防火墙打开时,它失败并出现异常
>gradle test
:compileJava
Note: PATH\TimeServer.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
Unexpected exception thrown.
org.gradle.messaging.remote.internal.MessageIOException: Could not write message [EndOfStream] to '/127.0.0.1:58895'.
at org.gradle.messaging.remote.internal.inet.SocketConnection.dispatch(SocketConnection.java:111)
at org.gradle.messaging.remote.internal.hub.MessageHub$ConnectionDispatch.run(MessageHub.java:284)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: An existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:51)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
at org.gradle.messaging.remote.internal.inet.SocketConnection$SocketOutputStream.flush(SocketConnection.java:236)
at org.gradle.messaging.remote.internal.inet.SocketConnection.dispatch(SocketConnection.java:109)
... 6 more
BUILD SUCCESSFUL
发生了什么事?
为什么引用的端口 58895
与打开的端口 9123
非常不同?
如何进行此测试运行 w/o 禁用防火墙?
要将哪个程序添加到 windows 防火墙的白名单以进行此测试 运行 可以吗?
这可能与 gradle 处理 System.exit()
呼叫的方式有关,参见 GRADLE-2759。
根据经验,在测试中调用 System.exit()
不是一个好主意,因为它可能会扰乱测试框架(如果一切都从同一个 JVM 启动怎么办?你会突然关闭它)。您应该添加一种正常关闭服务器的方法。
请注意,网络错误似乎与您的网络代码或服务器没有任何关系:您可以从堆栈跟踪 (org.gradle.messaging.remote.internal
) 中的包名称中看出它来自 Gradle。这就是端口与您指定的端口不同且无关的原因。
虽然 Windows 防火墙关闭,但不知道为什么这会通过。
我写了一个简单的测试项目,打开9123
端口一段时间后退出:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Date;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class TimeServer
{
private static final int PORT = 9123;
public static void main( String[] args ) throws IOException
{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
acceptor.setHandler( new TimeServerHandler() );
acceptor.getSessionConfig().setReadBufferSize( 2048 );
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind( new InetSocketAddress(PORT) );
}
private static class TimeServerHandler extends IoHandlerAdapter {
@Override
public void exceptionCaught(IoSession session, Throwable cause ) throws Exception
{
cause.printStackTrace();
}
@Override
public void messageReceived( IoSession session, Object message ) throws Exception
{
String str = message.toString();
if( str.trim().equalsIgnoreCase("quit") ) {
session.close();
return;
}
Date date = new Date();
session.write( date.toString() );
System.out.println("Message written...");
}
@Override
public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
{
System.out.println( "IDLE " + session.getIdleCount( status ));
}
}
}
...
import java.io.IOException;
public class TimeServerTest {
@Test
public void runningTimeServerForTime() throws IOException, InterruptedException {
int period = 15000;
System.out.println("Running time server for " + period + "ms");
TimeServer.main(new String[] {});
Thread.sleep(period);
System.out.println("Done, exiting");
System.exit(0);
}
}
此测试 运行 在 IntelliJ 下正常并且 Windows 防火墙关闭时。
当 windows 防火墙打开时,它失败并出现异常
>gradle test
:compileJava
Note: PATH\TimeServer.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
Unexpected exception thrown.
org.gradle.messaging.remote.internal.MessageIOException: Could not write message [EndOfStream] to '/127.0.0.1:58895'.
at org.gradle.messaging.remote.internal.inet.SocketConnection.dispatch(SocketConnection.java:111)
at org.gradle.messaging.remote.internal.hub.MessageHub$ConnectionDispatch.run(MessageHub.java:284)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: An existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:51)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
at org.gradle.messaging.remote.internal.inet.SocketConnection$SocketOutputStream.flush(SocketConnection.java:236)
at org.gradle.messaging.remote.internal.inet.SocketConnection.dispatch(SocketConnection.java:109)
... 6 more
BUILD SUCCESSFUL
发生了什么事?
为什么引用的端口 58895
与打开的端口 9123
非常不同?
如何进行此测试运行 w/o 禁用防火墙?
要将哪个程序添加到 windows 防火墙的白名单以进行此测试 运行 可以吗?
这可能与 gradle 处理 System.exit()
呼叫的方式有关,参见 GRADLE-2759。
根据经验,在测试中调用 System.exit()
不是一个好主意,因为它可能会扰乱测试框架(如果一切都从同一个 JVM 启动怎么办?你会突然关闭它)。您应该添加一种正常关闭服务器的方法。
请注意,网络错误似乎与您的网络代码或服务器没有任何关系:您可以从堆栈跟踪 (org.gradle.messaging.remote.internal
) 中的包名称中看出它来自 Gradle。这就是端口与您指定的端口不同且无关的原因。
虽然 Windows 防火墙关闭,但不知道为什么这会通过。