diff --git a/modules/registrars/cozaepp/Net/EPP/Client.php b/modules/registrars/cozaepp/Net/EPP/Client.php
index 84208d08f1398ac4939f21e2ac3288a2ac8a3a3d..7ba2c22e5d19cc824ad9e151dcaed32de72ee981 100644
--- a/modules/registrars/cozaepp/Net/EPP/Client.php
+++ b/modules/registrars/cozaepp/Net/EPP/Client.php
@@ -60,17 +60,25 @@
 
 			} else {
 				$result = stream_socket_client($target, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT);
-
 			}
 			if (!$result) {
 				return new PEAR_Error("Error connecting to $target: $errstr (code $errno)");
 
-			} else {
-				$this->socket = $result;
-				return $this->getFrame();
+			}
+
+			// Set our socket
+			$this->socket = $result;
 
+			// Set stream timeout
+			if (!stream_set_timeout($this->socket,$timeout)) {
+				return new PEAR_Error("Failed to set timeout on socket: $errstr (code $errno)");
+			}
+			// Set blocking
+			if (!stream_set_blocking($this->socket,0)) {
+				return new PEAR_Error("Failed to set blocking on socket: $errstr (code $errno)");
 			}
 
+			return $this->getFrame();
 		}
 
 		/**
@@ -101,7 +109,9 @@
 		* @return PEAR_Error|string the frame returned by the server, or an error object
 		*/
 		function request($xml) {
-			$this->sendFrame($xml);
+			if (PEAR::isError($res = $this->sendFrame($xml))) {
+				return $res;
+			}
 			return $this->getFrame();
 		}
 
diff --git a/modules/registrars/cozaepp/Net/EPP/Protocol.php b/modules/registrars/cozaepp/Net/EPP/Protocol.php
index 3574a4501b6b76868359cd970bd1cc3df6747efe..b12f481268872d099f2e75122cba73886082bc24 100644
--- a/modules/registrars/cozaepp/Net/EPP/Protocol.php
+++ b/modules/registrars/cozaepp/Net/EPP/Protocol.php
@@ -32,24 +32,49 @@ require_once('PEAR.php');
 */
 class Net_EPP_Protocol {
 
+	static function _fread_nb($socket,$length) {
+		$result = '';
+
+		// Loop reading and checking info to see if we hit timeout
+		$info = stream_get_meta_data($socket);
+		while (!$info['timed_out'] && !feof($socket)) {
+			// Try read remaining data from socket
+			$buffer = @fread($socket,$length - strlen($result));
+			// If the buffer actually contains something then add it to the result
+			if ($buffer !== false) {
+				$result .= $buffer;
+				// If we hit the length we looking for, break
+				if (strlen($result) == $length) {
+					break;
+				}
+			} else {
+				// Sleep 0.25s
+	       	 		usleep(2500);
+			}
+			// Update metadata
+			$info = stream_get_meta_data($socket);
+		}
+
+		// Check for timeout
+		if ($info['timed_out']) {
+			return new PEAR_Error('Timeout while reading data from socket');
+		}
+
+		return $result;
+	}
+
 	/**
 	* get an EPP frame from the remote peer
 	* @param resource $socket a socket connected to the remote peer
 	* @return PEAR_Error|string either an error or a string
 	*/
 	static function getFrame($socket) {
-
-		# NK: Use non-blocking IO
-		$hdr = "";
-		while (strlen($hdr) < 4)  {
-			if (@feof($socket)) return new PEAR_Error('Connection closed (socket is EOF)');
-			if (($hdrstr = @fread($socket,4 - strlen($hdr))) !== false) {
-		        $hdr .= $hdrstr;
-			} else {
-          		return new PEAR_ERROR('Error reading from socket:'.$php_errormsg);
-			}
+		// Read header
+		if (PEAR::isError($hdr = Net_EPP_Protocol::_fread_nb($socket,4))) {
+	       		return $hdr;
 		}
 
+		// Unpack first 4 bytes which is our length
 		$unpacked = unpack('N', $hdr);
 		$length = $unpacked[1];
 		if ($length < 5) {
@@ -57,19 +82,8 @@ class Net_EPP_Protocol {
 
 		} else {
 			$length -= 4; // discard the length of the header itself
-
-			// sometimes the socket can be buffered with a limit below the frame
-			// length, so we continually read from the socket until we get the full frame:
-			$frame = '';
-			while (strlen($frame) < $length) $frame .= fread($socket, ($length));
-
-			if (strlen($frame) > $length) {
-				return new PEAR_Error(sprintf("Frame length (%d bytes) doesn't match header (%d bytes)", strlen($frame), ($length)));
-
-			} else {
-				return $frame;
-
-			}
+			// Read frame
+			return Net_EPP_Protocol::_fread_nb($socket,$length);
 		}
 	}
 
@@ -79,6 +93,14 @@ class Net_EPP_Protocol {
 	* @param string $xml the XML to send
 	*/
 	static function sendFrame($socket, $xml) {
-		fwrite($socket, pack('N', (strlen($xml)+4)).$xml);
+		// Grab XML length & add on 4 bytes for the counter
+		$length = strlen($xml) + 4;
+		$res = fwrite($socket, pack('N',$length) . $xml);
+		// Check our write matches
+		if ($length != $res) {
+			return new PEAR_Error("Short write when sending XML");
+		}
+
+		return $res;
 	}
 }