As others have noted, this usually happens because both sides wrote data and one side didn't read it before calling close().
Here's a little reproducer: https://gist.github.com/jcalvinowens/da57edda9a01ca9f4c4088a...
$ gcc -O2 test.c -o test
$ strace -e socket,connect,write,accept,read,close ./test --rx
<...>
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
accept(3, NULL, NULL) = 4
close(3) = 0
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
<...>
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 3035
read(4, "", 4096) = 0
close(4) = 0
+++ exited with 0 +++
$ strace -e socket,connect,write,accept,read,close ./test --tx
<...>
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
write(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 600000) = 600000
close(3) = 0
+++ exited with 0 +++
...versus: $ gcc -O2 -DWRITE_TO_SOCKET_BEFORE_READ test.c -o test
$ strace -e socket,connect,write,accept,read,close ./test --rx
<...>
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
accept(3, NULL, NULL) = 4
close(3) = 0
write(4, "\250\3\0\0\0\0\0\0\250\3\0\0\0\0\0\0$\0\0\0\0\0\0\0$\0\0\0\0\0\0\0"..., 4096) = 4096
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
<...>
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 997
read(4, 0x7ffd45c2d3c0, 4096) = -1 ECONNRESET (Connection reset by peer)
<...>
+++ exited with 1 +++
$ strace -e socket,connect,write,accept,read,close ./test --tx
<...>
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
write(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 600000) = 600000
close(3)
+++ exited with 0 +++