diff --git a/lib/Connection.js b/lib/Connection.js
index 76fcbb049..2d7f46c37 100644
--- a/lib/Connection.js
+++ b/lib/Connection.js
@@ -15,8 +15,9 @@ function Connection(options) {
 
   this.config = options.config;
 
-  this._socket        = options.socket;
+  this._socket        = null;
   this._protocol      = new Protocol({config: this.config, connection: this});
+  this._protocolSetup = false;
   this._connectCalled = false;
   this.state          = 'disconnected';
   this.threadId       = null;
@@ -67,19 +68,29 @@ Connection.prototype.connect = function connect(options, callback) {
     options = {};
   }
 
+  this._setupProtocolHandlers();
+  this._protocol.handshake(options, wrapCallbackInDomain(this, callback));
+
   if (!this._connectCalled) {
     this._connectCalled = true;
+    this._socket        = null;
 
-    // Connect either via a UNIX domain socket or a TCP socket.
-    this._socket = (this.config.socketPath)
-      ? Net.createConnection(this.config.socketPath)
-      : Net.createConnection(this.config.port, this.config.host);
+    try {
+      // Connect either via a UNIX domain socket or a TCP socket.
+      this._socket = (this.config.socketPath)
+        ? Net.createConnection(this.config.socketPath)
+        : Net.createConnection(this.config.port, this.config.host);
+    } catch (err) {
+      this._handleNetworkError(err);
+      return;
+    }
 
     // Connect socket to connection domain
     if (Events.usingDomains) {
       this._socket.domain = this.domain;
     }
 
+    // socket <-> protocol
     var connection = this;
     this._protocol.on('data', function(data) {
       connection._socket.write(data);
@@ -94,15 +105,11 @@ Connection.prototype.connect = function connect(options, callback) {
       connection._protocol.end();
     }));
 
+    // Set up socket handlers
     this._socket.on('error', this._handleNetworkError.bind(this));
     this._socket.on('connect', this._handleProtocolConnect.bind(this));
-    this._protocol.on('handshake', this._handleProtocolHandshake.bind(this));
-    this._protocol.on('initialize', this._handleProtocolInitialize.bind(this));
-    this._protocol.on('unhandledError', this._handleProtocolError.bind(this));
-    this._protocol.on('drain', this._handleProtocolDrain.bind(this));
-    this._protocol.on('end', this._handleProtocolEnd.bind(this));
-    this._protocol.on('enqueue', this._handleProtocolEnqueue.bind(this));
 
+    // Set connect timeout
     if (this.config.connectTimeout) {
       var handleConnectTimeout = this._handleConnectTimeout.bind(this);
 
@@ -112,8 +119,6 @@ Connection.prototype.connect = function connect(options, callback) {
       });
     }
   }
-
-  this._protocol.handshake(options, wrapCallbackInDomain(this, callback));
 };
 
 Connection.prototype.changeUser = function changeUser(options, callback) {
@@ -241,18 +246,28 @@ Connection.prototype.end = function end(options, callback) {
 
 Connection.prototype.destroy = function() {
   this.state = 'disconnected';
-  this._implyConnect();
-  this._socket.destroy();
+  this._setupProtocolHandlers();
+
+  if (this._socket) {
+    this._socket.destroy();
+  }
+
   this._protocol.destroy();
 };
 
 Connection.prototype.pause = function() {
-  this._socket.pause();
+  if (this._socket) {
+    this._socket.pause();
+  }
+
   this._protocol.pause();
 };
 
 Connection.prototype.resume = function() {
-  this._socket.resume();
+  if (this._socket) {
+    this._socket.resume();
+  }
+
   this._protocol.resume();
 };
 
@@ -450,11 +465,25 @@ Connection.prototype._handleProtocolEnqueue = function _handleProtocolEnqueue(se
 };
 
 Connection.prototype._implyConnect = function() {
-  if (!this._connectCalled) {
+  this._setupProtocolHandlers();
+
+  if (!this._connectCalled && !this._protocol._destroyed) {
     this.connect();
   }
 };
 
+Connection.prototype._setupProtocolHandlers = function _setupProtocolHandlers() {
+  if (!this._protocolSetup) {
+    this._protocolSetup = true;
+    this._protocol.on('handshake', this._handleProtocolHandshake.bind(this));
+    this._protocol.on('initialize', this._handleProtocolInitialize.bind(this));
+    this._protocol.on('unhandledError', this._handleProtocolError.bind(this));
+    this._protocol.on('drain', this._handleProtocolDrain.bind(this));
+    this._protocol.on('end', this._handleProtocolEnd.bind(this));
+    this._protocol.on('enqueue', this._handleProtocolEnqueue.bind(this));
+  }
+};
+
 function createSecureContext (config, cb) {
   var context = null;
   var error   = null;
diff --git a/lib/protocol/Protocol.js b/lib/protocol/Protocol.js
index ab371059b..34bfa23c2 100644
--- a/lib/protocol/Protocol.js
+++ b/lib/protocol/Protocol.js
@@ -186,7 +186,7 @@ Protocol.prototype._enqueue = function(sequence) {
     sequence.on('end', function () {
       self._handshaked = true;
 
-      if (!self._fatalError) {
+      if (!self._fatalError && !self._destroyed) {
         self.emit('handshake', self._handshakeInitializationPacket);
       }
     });
diff --git a/test/unit/connection/test-connect-bogus-port.js b/test/unit/connection/test-connect-bogus-port.js
new file mode 100644
index 000000000..1fbf5ba3f
--- /dev/null
+++ b/test/unit/connection/test-connect-bogus-port.js
@@ -0,0 +1,17 @@
+var assert = require('assert');
+var common = require('../../common');
+
+var connection = common.createConnection({
+  port: 99999
+});
+
+connection.connect(function (err) {
+  assert.ok(err);
+  assert.strictEqual(err.fatal, true);
+  assert.ok(
+    err.code === 'ECONNREFUSED' /* Node.js < 0.12 */ ||
+    err.code === 'ERR_SOCKET_BAD_PORT' /* Node.js > 8 */ ||
+    err.name === 'RangeError'
+  );
+  connection.destroy();
+});