迷你网络服务器模拟:java.net.SocketException:连接重置
我制作了一个小型“网络服务器”作为 JUnit 测试的模拟。这是“网络服务器”的代码:
while(true) {
try {
ServerSocket socket = new ServerSocket(port);
socket.setReuseAddress(true);
Socket remote = s.accept();
PrintWriter out = new PrintWriter(remote.getOutputStream(), true);
out.append("some data");
out.flush();
out.close();
remote.close();
socket.close();
}
catch (IOException e) {
throw new RuntimeException(e);
}
这就是我在程序代码中所做的事情:
URL url = new URL(urlstr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.connect();
MyClass myClass = (MyClass) unmarshaller.unmarshal(con.getInputStream());
con.disconnect();
return myClass;
这里是我的问题:有时有效,有时无效。我不知道为什么。我收到此错误:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:180)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:230)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:270)
at java.io.BufferedInputStream.read(BufferedInputStream.java:329)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:688)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:653)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1067)
at my.program.Program.myMethod(...)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.junit.runners.Suite.runChild(Suite.java:115)
at org.junit.runners.Suite.runChild(Suite.java:23)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
为什么它有时会起作用?为什么有时不呢?怎么了?我必须运行我的 junit 测试 5 到 10 次才能让它工作一次。
I have made a small "webserver" as a mock for my JUnit tests. this is the code of the "webserver":
while(true) {
try {
ServerSocket socket = new ServerSocket(port);
socket.setReuseAddress(true);
Socket remote = s.accept();
PrintWriter out = new PrintWriter(remote.getOutputStream(), true);
out.append("some data");
out.flush();
out.close();
remote.close();
socket.close();
}
catch (IOException e) {
throw new RuntimeException(e);
}
and this is what i am doing in the code of the program:
URL url = new URL(urlstr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.connect();
MyClass myClass = (MyClass) unmarshaller.unmarshal(con.getInputStream());
con.disconnect();
return myClass;
here my problem: sometimes it works, sometimes not. and i don't know why. i get this error:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:180)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:230)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:270)
at java.io.BufferedInputStream.read(BufferedInputStream.java:329)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:688)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:653)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1067)
at my.program.Program.myMethod(...)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.junit.runners.Suite.runChild(Suite.java:115)
at org.junit.runners.Suite.runChild(Suite.java:23)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
why it's working sometimes? and why sometimes not? what is wrong? i have to run my junit test 5 or 10 times to get it work one time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
间接的答案是:不要尝试自己做。使用嵌入式 Simple 或 Jetty 服务器。使用大致相同数量的代码,您将获得超出您所拥有的相对大量的功能,并且您也不会遇到像这样的奇怪问题。
发生“连接重置”是因为您在 url 连接准备好之前关闭了套接字。
An indirect answer: don't try to do it yourself. Use an embedded Simple or Jetty server. With roughly the same amount of code, you'll get a relatively huge amount of functionality beyond what you have, and you won't encounter strange problems like this, either.
The "connection reset" is happening because you're closing the socket before the url connection is ready for you to do so.
您发布的代码块执行 HTTP 连接和响应的解组。当关注点很好分离时,单元测试效果最好。这意味着为连接和解组逻辑创建单独的类。完成此操作后,您可以使用如下代码测试解组:
您现在可以使用任何类型的 InputStream 测试解组器。在本例中,我使用了磁盘中的示例 XML 文件。
The code block you've posted performs both the HTTP connection and the unmarshalling of the response. Unit testing works best when there is good separation of concerns. That means create separate classes for the connection and the unmarshalling logic. Once you've done this, you can test just the unmarshalling with code like this:
You can now test your unmarshaller with any type of InputStream. In this case, I've used a sample XML file from disk.