diff --git a/libraries/net/message_oriented_connection.cpp b/libraries/net/message_oriented_connection.cpp
index 3ddc54a34..0bc2145ab 100644
--- a/libraries/net/message_oriented_connection.cpp
+++ b/libraries/net/message_oriented_connection.cpp
@@ -172,6 +172,7 @@ namespace graphene { namespace net {
 
       fc::oexception exception_to_rethrow;
       bool call_on_connection_closed = false;
+      bool io_error = false;
 
       try
       {
@@ -179,7 +180,12 @@ namespace graphene { namespace net {
         char buffer[BUFFER_SIZE];
         while( true )
         {
-          _sock.read(buffer, BUFFER_SIZE);
+          try {
+            _sock.read(buffer, BUFFER_SIZE);
+          } catch ( const fc::canceled_exception& ) {
+            io_error = true;
+            throw;
+          }
           _bytes_received += BUFFER_SIZE;
           memcpy((char*)&m, buffer, sizeof(message_header));
           FC_ASSERT( m.size.value() <= MAX_MESSAGE_SIZE, "", ("m.size",m.size.value())("MAX_MESSAGE_SIZE",MAX_MESSAGE_SIZE) );
@@ -189,7 +195,12 @@ namespace graphene { namespace net {
           std::copy(buffer + sizeof(message_header), buffer + sizeof(buffer), m.data.begin());
           if (remaining_bytes_with_padding)
           {
-            _sock.read(&m.data[LEFTOVER], remaining_bytes_with_padding);
+            try {
+              _sock.read(&m.data[LEFTOVER], remaining_bytes_with_padding);
+            } catch ( const fc::canceled_exception& ) {
+              io_error = true;
+              throw;
+            }
             _bytes_received += remaining_bytes_with_padding;
           }
           m.data.resize(m.size.value()); // truncate off the padding bytes
@@ -214,8 +225,20 @@ namespace graphene { namespace net {
       }
       catch ( const fc::canceled_exception& e )
       {
-        wlog( "caught a canceled_exception in read_loop.  this should mean we're in the process of deleting this object already, so there's no need to notify the delegate: ${e}", ("e", e.to_detail_string() ) );
-        throw;
+        if( io_error )
+        {
+          wlog( "disconnected on io error ${e}", ("e", e.to_detail_string() ) );
+          call_on_connection_closed = true;
+          exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected on io error: ${e}",
+                                                         ("e", e.to_detail_string())));
+        }
+        else
+        {
+          wlog( "caught a canceled_exception in read_loop.  this should mean we're in the process of deleting "
+                "this object already, so there's no need to notify the delegate: ${e}",
+                ("e", e.to_detail_string() ) );
+          throw;
+        }
       }
       catch ( const fc::eof_exception& e )
       {