src/socket_io.cpp
// Write out the length (in text form) prior to the string itself.
// We write out the length as a fixed 10 byte value.
Write out the length (in text form) prior to the string itself.
We write out the length as a fixed 10 byte value.
Write out the length ( in text form ) prior to the string itself . We write out the length as a fixed 10 byte value .
bool SocketIO::WriteMessage(const string &str) const {
  if (str.size() > kMaxMessageLen) {
    Warning("String size too long: %lli?!?\n", (long long int)str.size());
    return false;
  }
  int len = str.size();
  char buf[100];
  sprintf(buf, "%.10i", len);
  if (write(fd_, (void *)buf, 10) != 10) {
    return false;
  }
  int cum = 0;
  int rem = len;
  int us_delay = 1;
  while (rem > 0) {
    int written = write(fd_, (void *)(str.c_str() + cum), rem);
    if (written <= 0) {
      if (written < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
	Warning("SocketIO:WriteMessage(): write() returned %i errno %i (len %i cum %i rem %i)\n",
		written, errno, len, cum, rem);
	return false;
      }
    }
    if (written > 0) {
      cum += written;
      rem -= written;
      us_delay = 1;
    } else {
      if (us_delay == 8388608) {
	Warning("SocketIO:WriteMessage(): Couldn't write (len %i cum %i rem %i); errno %i\n",
		written, len, cum, rem, errno);
	return false;
      }
      usleep(us_delay);
      us_delay *= 2;
    }
  }
  return true;
}
bool SocketIO :: WriteMessage ( const string & str ) const { if ( str . size ( ) > kMaxMessageLen ) { Warning ( " \n " , ( long long int ) str . size ( ) ) ; return false ; } int len = str . size ( ) ; char buf [ 100 ] ; sprintf ( buf , " " , len ) ; if ( write ( fd_ , ( void * ) buf , 10 ) != 10 ) { return false ; } int cum = 0 ; int rem = len ; int us_delay = 1 ; while ( rem > 0 ) { int written = write ( fd_ , ( void * ) ( str . c_str ( ) + cum ) , rem ) ; if ( written <= 0 ) { if ( written < 0 && errno != EAGAIN && errno != EWOULDBLOCK ) { Warning ( " \n " , written , errno , len , cum , rem ) ; return false ; } } if ( written > 0 ) { cum += written ; rem -= written ; us_delay = 1 ; } else { if ( us_delay == 8388608 ) { Warning ( " \n " , written , len , cum , rem , errno ) ; return false ; } usleep ( us_delay ) ; us_delay *= 2 ; } } return true ; }
Write out the length (in text form) prior to the string itself.
Write out the length ( in text form ) prior to the string itself .
// 10^9 seems like more than enough. // Each time through this loop we try to write all the remaining bytes to the socket.  But // write() may fail to do so.  It may write some positive number of bytes.  It may return -1 // and set errno to EAGAIN or EWOULDBLOCK.  This is not an error; it just means we need to // wait a bit for the socket to clear.  This is only possible for non-blocking sockets, but // currently NBSocketIO inherits this method. // We succeeded in writing *something* (maybe everything).  Update cum and rem and reset // the sleep delay to 1 microsecond. // We failed to write anything, but it was not an error; we just need to wait and try // again.  We sleep with an exponentially increasing delay to avoid a busy loop. // But at some point we have to give up. // Double the delay each time through this loop.