title: Python3: Connection reset by peer while reading line from socket
body: <p>I get an <code>Connection reset by peer</code> error message while running this python3 script:</p>
  <pre><code>import struct, socket
  
  HOST = &quot;127.0.0.1&quot;
  PORT = 64012
  
  # read bytes from socket and return it as ascii representation
  def read_line_from_socket(s): 
      buf= &quot;&quot;
      while True:
          byteData = s.recv(1)
          if byteData == b&quot;\n&quot;:
              break
          buf += byteData.decode(&quot;ascii&quot;)
      return buf
  
  def read_four_longs_for_addition(s):
      sum = 0
      counter = 1
      while counter &lt;= 4:
          sum += struct.unpack(&quot;I&quot;, s.recv(4))[0]
          counter += 1 # python does not support ++, += 1 has to be used
      print(sum) # sum overflows int (number &gt; 32 bit)
      return sum
  
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
      s.connect((HOST,PORT))
      print(read_line_from_socket(s))
      print(read_line_from_socket(s))
      s.send(struct.pack(&quot;l&quot;, read_four_longs_for_addition(s)))
      # print(s.recv(32)) # receives &quot;You have succes..&quot;, NOT resulting in an Connection reset by peer which indicates success
      print(read_line_from_socket(s)) # results in &quot;Connection reset by peer&quot;
      s.close()
  </code></pre>
  <p>The code on the server which is communicating with my client socket looks like this:</p>
  <pre><code>#define BANNER \
    &quot;Welcome to &quot; LEVELNAME &quot;, brought to you by https://exploit.education&quot;
  
  int main(int argc, char **argv) {
    int i;
    unsigned long quad[sizeof(long)], result, wanted;
  
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
    printf(&quot;%s\nFor this level, sizeof(long) == %d, keep that in mind :)\n&quot;,
        BANNER, (int)sizeof(long));
  
    if (getrandom((void *)&amp;quad, sizeof(quad), 0) != sizeof(quad)) {
      errx(1, &quot;unable to getrandom(%d bytes)&quot;, sizeof(quad));
    }
  
    result = 0;
    for (i = 0; i &lt; sizeof(long); i++) {
      result += quad[i];
      if (write(1, (void *)&amp;quad[i], sizeof(long)) != sizeof(long)) {
        errx(1, &quot;Why have you foresaken me, write()&quot;);
      }
    }
  
    if (read(0, (void *)&amp;wanted, sizeof(long)) != sizeof(long)) {
      errx(1, &quot;Unable to read\n&quot;);
    }
  
    if (result == wanted) {
      printf(&quot;You have successfully passed this level, well done!\n&quot;);
    } else {
      printf(&quot;Whoops, better luck next time. Receieved %lu, wanted %lu\n&quot;, wanted,
          result);
    }
  
    return 0;
  }
  
  </code></pre>
  <p>Expected behavior:</p>
  <p>After successfully sending the correct sum of the received long values my script reads the last line &quot;You have successfully passed this level, well done!\n&quot; until the <code>&quot;\n&quot;</code> new line, prints it out to the screen and finally closing the socket connection.</p>
  <p>Actual output:</p>
  <pre><code>Welcome to phoenix/net-two, brought to you by https://exploit.education
  For this level, sizeof(long) == 4, keep that in mind :)
  9057758327
  Traceback (most recent call last):
    File &quot;net-2.py&quot;, line 31, in &lt;module&gt;
      print(read_line_from_socket(s))
    File &quot;net-2.py&quot;, line 10, in read_line_from_socket
      byteData = s.recv(1)
  ConnectionResetError: [Errno 104] Connection reset by peer
  
  </code></pre>
  <p>Looking at the process with <code>strace python3 nameOfPythonScript.py</code>, I can't see any problem and everything should be working fine:</p>
  <pre><code>recvfrom(3, &quot;n&quot;, 1, 0, NULL, NULL)      = 1
  recvfrom(3, &quot;e&quot;, 1, 0, NULL, NULL)      = 1
  recvfrom(3, &quot;!&quot;, 1, 0, NULL, NULL)      = 1
  recvfrom(3, &quot;\n&quot;, 1, 0, NULL, NULL)     = 1
  write(1, &quot;You have successfully passed thi&quot;..., 52You have successfully passed this level, well done!
  ) = 52
  close(3)                                = 0
  rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ffff7bcd0c0}, {sa_handler=0x5555557d8980, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ffff7bcd0c0}, 8) = 0
  munmap(0x7ffff6c0e000, 262144)          = 0
  exit_group(0)                           = ?
  +++ exited with 0 +++
  </code></pre>
  <p>My question:</p>
  <p>Why does the Connection reset occur? Does it have to do with the <code>return 0;</code> in the server program code? Note that if I <code>recv</code> a fixed number of bytes instead of trying to read the complete last line the error does not occur (see comments in my script's code)</p>