前頁の考察から、TCP connection に対し iostream 化する ことを考える。とりあえず buffer pointer を渡さずに int underflow(); int uflow(); int overflow(int c=std::char_traits<char>::eof()); int sync(); だけを実装してみた。 host, port が与えられたとして try { char linebuf[1024]; SocketLibrary netlib; InternetAddress addr(host,port); TcpBuffer tcp(PF_INET, SOCK_STREAM); std::iostream strm((std::streambuf*)&tcp); if(tcp.connect(addr.socketaddress(), addr.addresslength()) != Socket::sockerr) { std::streamsize n; std::cout << "Connected" << std::endl; strm << "GET / HTTP/1.0"; strm.put(0x0d); strm.put(0x0a); strm.put(0x0d); strm.put(0x0a); strm.flush(); while(strm.getline(linebuf,1023)) { n = strm.gcount(); linebuf[n] = 0; std::cout << linebuf << std::endl; } n = strm.gcount(); if( n ) { linebuf[n] = 0; std::cout << linebuf << std::endl; } tcp.close(); } else { std::cout << "Connection fail" << std::endl; } } catch(...) { : } という使い方で動いた。CR(0x0d)/LF(0x0a) を endl() で 出せるようにするには、fstream の binary mode の not の 場合を見ればよいのかも知れない。 一応 putnl() という(CR/LF を置くだけで flush しない) マニピュレータ関数を用意してみた。iostream では write が 認識されないみたいで、とりあえず ostream と istream を 別々にして std::ostream& putnl(std::ostream& s) { static const char crlf[2] = { 0x0d, 0x0a }; return s.write(crlf, 2); } try { char linebuf[1024]; SocketLibrary netlib; InternetAddress addr(host,port); TcpBuffer tcp(PF_INET, SOCK_STREAM); std::ostream ostrm((std::streambuf*)&tcp); std::istream istrm((std::streambuf*)&tcp); if(tcp.connect(addr.socketaddress(), addr.addresslength()) != Socket::sockerr) { std::streamsize n; std::cout << "Connected" << std::endl; ostrm << "GET / HTTP/1.0" << putnl << putnl <<std::flush; while(istrm.getline(linebuf,1023)) { n = istrm.gcount(); linebuf[n] = 0; std::cout << linebuf << std::endl; } n = istrm.gcount(); if( n ) { linebuf[n] = 0; std::cout << linebuf << std::endl; } tcp.close(); } else { std::cout << "Connection fail" << std::endl; } } catch(...) { : } よく考えてみると、iostream は istream と ostream から派生しているので、 わざわざ分ける必要はない。try ブロックの中だけ示すと、 try { char linebuf[1024]; SocketLibrary netlib; InternetAddress addr(host,port); TcpBuffer tcp(PF_INET, SOCK_STREAM); std::iostream strm((std::streambuf*)&tcp); if(tcp.connect(addr.socketaddress(), addr.addresslength()) != Socket::sockerr) { std::streamsize n; std::cout << "Connected" << std::endl; strm << "GET / HTTP/1.0" << putnl << putnl <<std::flush; while(strm.getline(linebuf,1023)) { n = strm.gcount(); linebuf[n] = 0; std::cout << linebuf << std::endl; } n = strm.gcount(); if( n ) { linebuf[n] = 0; std::cout << linebuf << std::endl; } tcp.close(); } else { std::cout << "Connection fail" << std::endl; } } でよい。 |