迷你网络服务器模拟:java.net.SocketException:连接重置

发布于 2024-12-10 03:25:41 字数 4021 浏览 0 评论 0原文

我制作了一个小型“网络服务器”作为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋叶绚丽 2024-12-17 03:25:41

间接的答案是:不要尝试自己做。使用嵌入式 SimpleJetty 服务器。使用大致相同数量的代码,您将获得超出您所拥有的相对大量的功能,并且您也不会遇到像这样的奇怪问题。

发生“连接重置”是因为您在 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.

半寸时光 2024-12-17 03:25:41

您发布的代码块执行 HTTP 连接和响应的解组。当关注点很好分离时,单元测试效果最好。这意味着为连接和解组逻辑创建单独的类。完成此操作后,您可以使用如下代码测试解组:

class Unmarshaller {
  public MyClass unmarshal(InputStream is) {
    return (MyClass) unmarshaller.unmarsal(is);
  }
}

class UnmarshallerTests {
  @Test
  public void testUnmarshal() {
    Unmarshaller u = new Unmarshaller();
    FileInputStream fis = new FileInputStream("test-sample.xml");
    u.unmarshal(fis);
}

您现在可以使用任何类型的 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:

class Unmarshaller {
  public MyClass unmarshal(InputStream is) {
    return (MyClass) unmarshaller.unmarsal(is);
  }
}

class UnmarshallerTests {
  @Test
  public void testUnmarshal() {
    Unmarshaller u = new Unmarshaller();
    FileInputStream fis = new FileInputStream("test-sample.xml");
    u.unmarshal(fis);
}

You can now test your unmarshaller with any type of InputStream. In this case, I've used a sample XML file from disk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文