Skip to content

Instantly share code, notes, and snippets.

@knzm
Last active July 8, 2017 14:48
Show Gist options
  • Save knzm/af0743d8bc27ae4aa20865cbd3b776d5 to your computer and use it in GitHub Desktop.
Save knzm/af0743d8bc27ae4aa20865cbd3b776d5 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"io"
"log"
"net"
"os"
"syscall"
"time"
)
func IsNetworkErrorFatal(err error) bool {
if err == nil {
// no error
return false
}
if err == io.EOF {
// connection closed
return false
}
opErr, ok := err.(*net.OpError)
if !ok {
return true
}
if opErr.Timeout() || opErr.Temporary() {
return false
}
syscallErr, ok := opErr.Err.(*os.SyscallError)
if !ok {
return true
}
errno := syscallErr.Err
if errno == syscall.EPIPE || errno == syscall.ECONNRESET {
// connection closed
return false
}
return true
}
func main() {
// A problematic client
client := func(conn net.Conn) {
// send a request
_, err := conn.Write([]byte("ping\n"))
if err != nil {
log.Panic(err)
}
// then disconnect without reading any response
err = conn.Close()
if err != nil {
log.Panic(err)
}
}
// open a connection on the server side
listener, err := net.Listen("tcp", ":0")
if err != nil {
log.Panic(err)
}
addr := listener.Addr()
log.Printf("address: %s\n", addr)
go func() {
// open a connection on the client side
conn, err := net.Dial("tcp", addr.String())
if err != nil {
log.Panic(err)
}
client(conn)
}()
conn, err := listener.Accept()
if err != nil {
log.Panic(err)
}
// read from socket
r := bufio.NewReader(conn)
_, err = r.ReadString('\n')
if err != nil {
log.Panic(err)
}
// write to socket that is already closed repeatedly for a second
err = func(conn net.Conn) error {
timer := time.After(1 * time.Second)
for {
select {
case <-timer:
return nil
default:
}
b := make([]byte, 1)
_, err = conn.Write(b)
if err != nil {
return err
}
}
}(conn)
if err == nil {
log.Fatal("An error should be occured.")
}
if IsNetworkErrorFatal(err) {
log.Fatalf("Fatal error: %s\n", err)
}
log.Printf("non fatal error: %v\n", err)
err = conn.Close()
if err != nil {
log.Panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment