Oleg Sydorov
Oleg Sydorov

Reputation: 709

Go net conn.SetWriteDeadline function usage

I cannot understand how to use net conn.SetWriteDeadline function?

conn, err := net.DialTimeout("tcp", "10.1.10.1:2000", 3*time.Second)
    if err!=nil{
        fmt.Println("Error: ", err)
    }
//waits as expected 3 seconds and returns error if dial not succeeded

conn.SetWriteDeadline(time.Now().Add(5*time.Second))
    n, err:= conn.Write([]byte{0x00})

    if err != nil {
        fmt.Printf("Write: %v", err)
    }

    fmt.Println("Bytes wrote: ", n)
//always returns n=1, no wait, no error if connection lost.

I expect that conn.Write must try to write data to port during 5 seconds and then it must return n=0 and error if there is a trouble with connection. But, even if I unplug network cable, it returns no error and n=1.

If I try to do something like this,

for {
        conn.SetWriteDeadline(time.Now().Add(5 * time.Second))
        n, err = conn.Write(buffer)
        if err != nil {
            log.Println("Timeout error")            
        } else {
            break
        }
        if t.GetElapsed() >= 30*time.Second {
            err = errors.New("Connection timeout")
            break
        }
    }

I expect that there will be several attempts to write data, with escaping from FOR if succeeded, or via timeout. But behaviour is the same - even if network is disconnected, there is no error, there is only 1 iteration. What am I doing wrong? How to use? How to understand if data has been really written to port? How to handle disconnection?

Upvotes: 0

Views: 2200

Answers (1)

parzival
parzival

Reputation: 310

Your write has been accepted by the TCP stack, which now has its own mechanism to handle retries and failures. The write deadline does not guard against the condition you are creating. If you are expecting a response from the peer you are communicating with, use a read deadline. If the connection is terminated by the peer, either a read or a write should identify this condition with an error. Simply disconnecting the network will not make this happen in a timely fashion, but it TCP timeouts are used, the disconnection will eventually trigger an error.

Upvotes: 1

Related Questions