net.Listener Accept() timeout?

4,997 views
Skip to first unread message

al...@sneer.at

unread,
Dec 8, 2014, 3:37:27 PM12/8/14
to golan...@googlegroups.com
Hiho,

I want to timeout and close a listening socket when no client connects within 5 seconds.
So im stuck with the following code:

conchan := make(chan bool)
stop
:= false
var conn net.Conn

go func
() {
   
select {
       
case <-conchan:
         
...
         close
(conchan)
         
return
       
case <-time.After(time.Second * 5):
         
...
         e
:= listener.Close()
         stop
= true
         
if e != nil {
         fmt
.Printf("%v\n", e)
         
}
     
return
   
}
 
}()

// blocks
 conn
, _ = listener.Accept()
conchan
<- true




Now when someone connects within 5 seconds, a true is sent to conchan and that works fine.
But it doesnt matter if a client connects or not, after 5 seconds I land at the time.After case even when I previously ran into the conchan case and returned the function.
Is there a better/elegant way? Or what do I do wrong...

Any help highly appreciated.

nkatsaros

unread,
Dec 8, 2014, 5:44:32 PM12/8/14
to golan...@googlegroups.com
Use listener.SetDeadline(time.Now().Add(5*time.Second)) and then listener.Accept() will return an error if no connection is received after the deadline. You can assert the error to a *net.OpError (I think) using nErr, ok := err.(*net.OpError) and then check nErr.Timeout() to see if it was related to the deadline instead of a real error.

Dave Cheney

unread,
Dec 8, 2014, 6:19:47 PM12/8/14
to golan...@googlegroups.com
if err, ok := err.(*netOpError); ok && err.Timeout() {
   // it was a timeout

Alexander Frimmel

unread,
Dec 9, 2014, 4:00:43 AM12/9/14
to golan...@googlegroups.com
I saw that SetDeadline method before, but I made another mistake which was not shown in my posted code.

For the record:
I was using "listener net.Listener" as function parameter and "net.Listener" doesnt implement "SetDeadline". So I was struggling and just didn't recognize.
Switching to: "listener *net.TCPListener" and catching the timeout with your solution is working perfectly fine.

Thanks both of you!

Dave Cheney

unread,
Dec 9, 2014, 4:03:04 AM12/9/14
to Alexander Frimmel, golang-nuts
if l, ok := l.(*net.TCPListner); ok {
// l _is_ a *net.TCPListener inside this block
l.SetTimeout(9000 * time.Second)
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/kYI-xCyiZ0k/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages