-
-
Save ChyiYaqing/d8af6bb9a1a68ff21d5b2b8c32df1f2a to your computer and use it in GitHub Desktop.
Handle 'connection reset by peer' error in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"log" | |
"net" | |
"os" | |
"syscall" | |
"time" | |
) | |
func server() { | |
listener, err := net.Listen("tcp", ":8000") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer listener.Close() | |
conn, err := listener.Accept() | |
if err != nil { | |
log.Fatal("server", err) | |
os.Exit(1) | |
} | |
data := make([]byte, 1) | |
if _, err := conn.Read(data); err != nil { | |
log.Fatal("server", err) | |
} | |
conn.Close() | |
} | |
func client() { | |
conn, err := net.Dial("tcp", "localhost:8000") | |
if err != nil { | |
log.Fatal("client", err) | |
} | |
if _, err := conn.Write([]byte("ab")); err != nil { | |
log.Printf("client: %v", err) | |
} | |
time.Sleep(1 * time.Second) // wait for close on the server side | |
data := make([]byte, 1) | |
if _, err := conn.Read(data); err != nil { | |
log.Printf("client: %v", err) | |
if errors.Is(err, syscall.ECONNRESET) { | |
log.Print("This is connection reset by peer error") | |
} | |
} | |
} | |
func main() { | |
go server() | |
time.Sleep(3 * time.Second) // wait for server to run | |
client() | |
} | |
/* | |
Reproduce the connection reset by peer error | |
We can reproduce the error by creating a server and client that do the following: | |
1. the server reads a single byte and the closes the connection | |
2. the client sends more than one byte | |
If the server closes the connection with the remaining bytes in the socket's receive buffer, | |
then an RST packet is sent to the client. When the client tries to read from such a closed connection, | |
it will get the `connection reset by peer` error. | |
*/ |
Difference between connection reset by peer and broken pipe
Both connection reset by peer
and broken pipe
errors occur when a peer (the other end) unexpectedly closes the underlying connection. However, there is a subtle difference between them. Usually, you get the connection reset by peer
when you read from the connection after the server sends the RST
packet, and when you write to the connection after the RST
instead, you get the broken pipe
error.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Typically, you can see
connection reset by peer
error in response to a request being sent from the client to the server. It means that something bad has happended to the server: it has rebooted, the program has crashed, or other problems have occurred that cause the connection to be forcibly closed(强制关闭).Since TCP connections can be broken, there is no needed to handle the
connection reset by peer
in any special way on the client side. You can log the error, ignore it or retry the connection when it occurs.