mytcpbuf の実装

overflow と sync の実装

overflowは出力用bufferがfullになった時に呼ばれる。 一方、syncの方はbufferがfullであるかどうかに かかわらず出力を強制する場合に呼ばれる。

network出力では一度のsend callで全dataが 送られるとは限らない。 Ring buffer にして、送り残りがある場合でも これを残したまま回すと手もあるが、論理が少し面倒 になるので、一度に全dataを送ることにしよう。 まず、そのためのhelper関数を Richard Stevens の教科書、"UNIX Network Programming", ISBN 0-13-928755-8, Prentice-Hall, Inc.,(1994) から頂戴しておこう。

int
mytcpbuf::sendn(const char* buf, int nbytes)
{
  int nleft;
  int nsend;

  nleft = nbytes;
  while( nleft > 0 )
  {
    nsend = m_socket.send(buf, nleft);
    if( nsend <= 0 )
      break;
    nleft -= nsend;
    buf += nsend;
  }
  return (nbytes - nleft);
}

これを使って、

int
mytcpbuf::overflow(int c)
{
  int n = pptr() - pbase();
  if((n > 0) && (sendn(pbase(), n) != n))
    return std::char_traits<char>::eof();
  setp(m_sndbuf.begin(), m_sndbuf.end());
  if(c == std::char_traits<char>::eof())
    c = 0;
  else
  {
    *pbase() = (c & 255);
    pbump(1);
  }
  return c;
}

int
mytcpbuf::sync()
{
  int n = pptr() - pbase();
  if((n > 0) && (sendn(pbase(), n) != n))
    return std::char_traits<char>::eof();
  setp(m_sndbuf.begin(), m_sndbuf.end());
  return 0;
}

と書ける。ここでpbase()、pptr()は各々、出力 buffer の先頭位置、 出力の次位置を表す関数で基底classで与えられている。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-06-06 (火) 19:57:28