diff --git a/p2p/server.go b/p2p/server.go
index 7351a265441ad1de8737db3401e57094747b1c3d..d8be85323007b970241402226ad1634cc354374f 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -542,6 +542,10 @@ func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn)
 	}
 }
 
+type tempError interface {
+	Temporary() bool
+}
+
 // listenLoop runs in its own goroutine and accepts
 // inbound connections.
 func (srv *Server) listenLoop() {
@@ -561,16 +565,31 @@ func (srv *Server) listenLoop() {
 	}
 
 	for {
+		// Wait for a handshake slot before accepting.
 		<-slots
-		fd, err := srv.listener.Accept()
-		if err != nil {
-			return
+
+		var (
+			fd  net.Conn
+			err error
+		)
+		for {
+			fd, err = srv.listener.Accept()
+			if tempErr, ok := err.(tempError); ok && tempErr.Temporary() {
+				glog.V(logger.Debug).Infof("Temporary read error: %v", err)
+				continue
+			} else if err != nil {
+				glog.V(logger.Debug).Infof("Read error: %v", err)
+				return
+			}
+			break
 		}
-		mfd := newMeteredConn(fd, true)
+		fd = newMeteredConn(fd, true)
+		glog.V(logger.Debug).Infof("Accepted conn %v\n", fd.RemoteAddr())
 
-		glog.V(logger.Debug).Infof("Accepted conn %v\n", mfd.RemoteAddr())
+		// Spawn the handler. It will give the slot back when the connection
+		// has been established.
 		go func() {
-			srv.setupConn(mfd, inboundConn, nil)
+			srv.setupConn(fd, inboundConn, nil)
 			slots <- struct{}{}
 		}()
 	}