title: Why Socket does not throw error when unaccepted socket send a message?
body: <p>My goal is to create a server-client that accepts 1 connection and then the server exit with code 0.</p>
  <p>My expected result: 2nd client should fail to send message because <code>ServerSocket</code> either is closed or it does not accept the 2nd client with <code>serverSocket.accept()</code>.</p>
  <p>My actual result: 2nd client can send message without throwing error of <code>java.net.ConnectException: Connection refused: connect</code></p>
  <p>My actual result <code>EXTRA</code>: If you create the 2nd client on different method, it will fail.</p>
  <p>java/framework/Client.java</p>
  <pre><code>package framework;
  
  import java.io.IOException;
  import java.net.Socket;
  import java.nio.charset.StandardCharsets;
  
  public class Client {
    private final Socket socket;
  
    public Client() throws IOException {
      socket = new Socket(&quot;localhost&quot;, 80);
    }
  
    public void send(String message) throws IOException {
      socket.getOutputStream().write(message.getBytes(StandardCharsets.US_ASCII));
    }
  }
  
  </code></pre>
  <p>java/framework/Server.java</p>
  <pre><code>package framework;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.nio.charset.StandardCharsets;
  
  public class Server implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(Server.class);
  
    private final ServerSocket serverSocket;
  
    public Server() throws IOException {
      serverSocket = new ServerSocket(80);
    }
  
    @Override
    public void run() {
      try (serverSocket) {
        logger.debug(&quot;Sever socket started at port &quot; + serverSocket.getLocalPort());
  
        final Socket socket = serverSocket.accept();
        logger.debug(&quot;Socket accepted: &quot; + socket.getInetAddress());
  
        final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        final String line = reader.readLine();
        logger.debug(&quot;Input received: &quot; + line);
  
      } catch (IOException e) {
        logger.warn(&quot;something went wrong&quot; + e);
      }
  
      logger.debug(&quot;Server Socket closed.&quot;);
    }
  }
  
  </code></pre>
  <p>test/java/ServerClientTest.java</p>
  <pre><code>import framework.Client;
  import framework.Server;
  import org.junit.jupiter.api.Assertions;
  import org.junit.jupiter.api.BeforeAll;
  import org.junit.jupiter.api.Test;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.IOException;
  
  public class ServerClientTest {
    private static final Logger logger = LoggerFactory.getLogger(ServerClientTest.class);
  
    @BeforeAll
    static void if_server_can_start_then_success() {
      logger.debug(&quot;beforeAll&quot;);
      try {
        Server server = new Server();
        Thread thread = new Thread(server);
        thread.start();
      } catch (IOException ignored) {
        Assertions.fail(&quot;failed to start the server&quot;);
      }
    }
  
    @Test
    void if_1st_client_can_send_message_to_server_then_success() {
      try {
        Client client = new Client();
        client.send(&quot;Hello from 1st client\r\n&quot;);
  
        Client client1 = new Client();
        client1.send(&quot;Hello from 2nd client\r\n&quot;);
      } catch (IOException e) {
        Assertions.fail(&quot;1st client unable to send message to server. &quot; + e);
      }
    }
  }
  
  </code></pre>
  <p>Edit:</p>
  <ol>
  <li>do <code>logger.debug(&quot;Socket: &quot; + socket.getInputStream())</code> inside the Client class <code>send</code> method, magically, the socket will throw <code>java.net.SocketException. Connection reset by peer: socket write error</code>. While, calling <code>socket.isConnected()</code> will return true. Yes, I know, weird to call <code>getInputStream</code> and log it, but it makes the test works as expected.</li>
  </ol>
  <p>Log of original code:</p>
  <pre><code>23:37:02.418 [main] DEBUG ServerClientTest - beforeAll
  23:37:02.442 [Thread-0] DEBUG framework.Server - Sever socket started at port 80
  
  23:37:02.491 [Thread-0] DEBUG framework.Server - Socket accepted: /127.0.0.1
  23:37:02.492 [Thread-0] DEBUG framework.Server - Input received: Hello from 1st client
  23:37:02.493 [Thread-0] DEBUG framework.Server - Server Socket closed.
  
  
  Process finished with exit code 0
  </code></pre>
  <p>Log of calling <code>socket.getInputStream()</code> in the Client class <code>send</code> method.</p>
  <pre><code>23:39:48.098 [main] DEBUG ServerClientTest - beforeAll
  
  23:39:48.153 [Thread-0] DEBUG framework.Server - Sever socket started at port 80
  23:39:48.188 [Thread-0] DEBUG framework.Server - Socket accepted: /127.0.0.1
  23:39:48.188 [main] DEBUG framework.Client - Socket: java.net.SocketInputStream@6bf0219d
  23:39:48.190 [Thread-0] DEBUG framework.Server - Input received: Hello from 1st client
  23:39:48.191 [main] DEBUG framework.Client - Socket: java.net.SocketInputStream@36d585c
  23:39:48.191 [Thread-0] DEBUG framework.Server - Server Socket closed.
  
  
  org.opentest4j.AssertionFailedError: clients failed to send message.
  
      at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:43)
      at org.junit.jupiter.api.Assertions.fail(Assertions.java:129)
      at ServerClientTest.if_clients_can_send_message_to_server_then_success(ServerClientTest.java:35)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:566)
      at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
      at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
      at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
      at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
      at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
      at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
      at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
      at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
      at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
      at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
      at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
      at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
  Caused by: java.net.SocketException: Connection reset by peer: socket write error
      at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
      at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
      at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:138)
      at framework.Client.send(Client.java:20)
      at ServerClientTest.if_clients_can_send_message_to_server_then_success(ServerClientTest.java:33)
      ... 65 more
  
  
  
  Process finished with exit code -1
  
  </code></pre>