+  wxUint32 len, len2, sig, total;
+  bool error;
+  int old_flags;
+  struct
+  {
+    unsigned char sig[4];
+    unsigned char len[4];
+  } msg;
+
+  // Mask read events
+  m_reading = true;
+
+  total = 0;
+  error = true;
+  old_flags = m_flags;
+  SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
+
+  if (_Read(&msg, sizeof(msg)) != sizeof(msg))
+    goto exit;
+
+  sig = (wxUint32)msg.sig[0];
+  sig |= (wxUint32)(msg.sig[1] << 8);
+  sig |= (wxUint32)(msg.sig[2] << 16);
+  sig |= (wxUint32)(msg.sig[3] << 24);
+
+  if (sig != 0xfeeddead)
+  {
+    wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
+    goto exit;
+  }
+
+  len = (wxUint32)msg.len[0];
+  len |= (wxUint32)(msg.len[1] << 8);
+  len |= (wxUint32)(msg.len[2] << 16);
+  len |= (wxUint32)(msg.len[3] << 24);
+
+  if (len > nbytes)
+  {
+    len2 = len - nbytes;
+    len = nbytes;
+  }
+  else
+    len2 = 0;
+
+  // Don't attemp to read if the msg was zero bytes long.
+  if (len)
+  {
+    total = _Read(buffer, len);
+
+    if (total != len)
+      goto exit;
+  }
+  if (len2)
+  {
+    char *discard_buffer = new char[MAX_DISCARD_SIZE];
+    long discard_len;
+
+    // NOTE: discarded bytes don't add to m_lcount.
+    do
+    {
+      discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
+      discard_len = _Read(discard_buffer, (wxUint32)discard_len);
+      len2 -= (wxUint32)discard_len;
+    }
+    while ((discard_len > 0) && len2);
+
+    delete [] discard_buffer;
+
+    if (len2 != 0)
+      goto exit;
+  }
+  if (_Read(&msg, sizeof(msg)) != sizeof(msg))
+    goto exit;
+
+  sig = (wxUint32)msg.sig[0];
+  sig |= (wxUint32)(msg.sig[1] << 8);
+  sig |= (wxUint32)(msg.sig[2] << 16);
+  sig |= (wxUint32)(msg.sig[3] << 24);
+
+  if (sig != 0xdeadfeed)
+  {
+    wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
+    goto exit;
+  }
+
+  // everything was OK
+  error = false;
+
+exit:
+  m_error = error;
+  m_lcount = total;
+  m_reading = false;
+  SetFlags(old_flags);
+