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で与えられている。 |