This is a creation in Article, where the information may have evolved or changed.
How do I set a timeout before sending and receiving one connection at a time? I thought of a way to return the dial callback to the wrapped timeoutconn, indirectly invoke the real conn, so that you can set the time-out before each read and write.
The following is the modified experiment code:
////How to set timeout for HTTP. Get () in Golang// PackageMainImport("IO" "Io/ioutil" "Log" "NET" "Net/http" "Sync" "Time")typeTimeoutconnstruct{Conn Net. Conn timeout time. Duration}funcNEWTIMEOUTCONN (Conn net. Conn, timeout time. Duration) *timeoutconn {return&timeoutconn{conn:conn, Timeout:timeout,}}func(c *timeoutconn) Read (b []byte) (nint, err Error) {C.setreaddeadline (time. Now (). ADD (C.timeout))returnC.conn.read (b)}func(c *timeoutconn) Write (b []byte) (nint, err Error) {C.setwritedeadline (time. Now (). ADD (C.timeout))returnC.conn.write (b)}func(c *timeoutconn) Close () Error {returnC.conn.close ()}func(c *timeoutconn) LOCALADDR () net. Addr {returnC.CONN.LOCALADDR ()}func(c *timeoutconn) REMOTEADDR () net. Addr {returnC.CONN.REMOTEADDR ()}func(c *timeoutconn) Setdeadline (t time. Time) Error {returnC.conn.setdeadline (t)}func(c *timeoutconn) Setreaddeadline (t time. Time) Error {returnC.conn.setreaddeadline (t)}func(c *timeoutconn) Setwritedeadline (t time. Time) Error {returnC.conn.setwritedeadline (t)}funcMain () {client: = &http. client{Transport: &http. transport{Dial:func(NETW, addrstring) (NET. Conn, error) {log. Printf ("dial to%s://%s", NETW, ADDR) conn, err: = Net. Dialtimeout (NETW, addr, time. Second * *)ifErr! =Nil{return Nil, err}returnNEWTIMEOUTCONN (conn, time. Second * *),Nil}, Responseheadertimeout:time. Second *2,},} addr: = Starttestserver () sendtestrequest (client,"1st", addr,"Normal") Sendtestrequest (client,"2st", addr,"Normal") Sendtestrequest (client,"3st", addr,"Timeout") Sendtestrequest (client,"4st", addr,"Normal") time. Sleep (time. Second *3) Sendtestrequest (client,"5st", addr,"Normal")}funcStarttestserver ()string{Listener, err: = Net. Listen ("TCP",": 0")ifErr! =Nil{log. Fatalf ("Failed to listen-%s"Err. Error ())} WG: =New(Sync. WAITGROUP) WG. Add(1)Go func() {http. Handlefunc ("/normal",func(W http. Responsewriter, req *http. Request) {time. Sleep( +* time.millisecond) io. WriteString (W,"OK")}) http. Handlefunc ("/timeout",func(W http. Responsewriter, req *http. Request) {time. Sleep(2500* time.millisecond) io. WriteString (W,"OK")}) WG. Done () Err = http. Serve (Listener,Nil)ifErr! =Nil{log. Fatalf ("Failed to start HTTP server-%s"Err. Error ())}} () WG. Wait () log. Printf ("Start HTTP Server at http://%s/", Listener. ADDR ())returnListener. Addr (). String ()}funcSendtestrequest (client *http. Client, id, addr, pathstring{req, err: = http. Newrequest ("GET","http //"+addr+"/"+path,Nil)ifErr! =Nil{log. Fatalf ("New request failed-%s", err)} req. Header.add ("Connection","Keep-alive")SwitchPath { Case "Normal":ifRESP, err: = client. Do (req); Err! =Nil{log. Fatalf ("%s request failed-%s", ID, err)}Else{result, ERR2: = Ioutil. ReadAll (resp. Body)ifErr2! =Nil{log. Fatalf ("%s Response read failed-%s", ID, ERR2)} resp. Body.close () log. Printf ('%s request-%s ', ID, result)} Case "Timeout":if_, Err: = client. Do (req); Err = =Nil{log. Fatalf ('%s request not timeout ', id)}Else{log. Printf ('%s request-%s ', ID, err)}}}