#include <windows.h> #include <iostream> using namespace std; class tcpbuf : public streambuf { public: explicit tcpbuf(SOCKET& conn) : conn(conn) {} virtual ~tcpbuf() {} int write(const char* buf, const int n) { int res = ::send(conn, buf, n, 0); if(res < 0) { conn = NULL; } return n; } int read(char* buf, const int n) { int res = ::recv(conn, buf, n, 0); if(res < 0) { conn = NULL; } return res; } protected: virtual int overflow(int c) { if(sync() == EOF) { return EOF; } if(pbase() == 0) { doallocate(); } if(c != EOF) { *pptr() = c; pbump(1); } return 0; } virtual int underflow() { if(gptr() < egptr()) return *(unsigned char*)gptr(); if(sync() == EOF) return EOF; if(pbase() == 0) doallocate(); const int count = read(pbase(), egptr() - pbase()); setg(pbase(), pbase(), pbase() + (count <= 0 ? 0 : count)); setp(pbase(), pbase()); return count <= 0 ? EOF : *(unsigned char*)gptr(); } virtual int sync(void) { const int n = pptr() - pbase(); if(n == 0) { return 0; } return write(pbase(), n) == n ? (pbump(-n), 0) : EOF; } virtual int doallocate(void) { const int size = 512; char *p = (char *) malloc(size); setp(p, p+size); setg(p, p, p+size); return 1; } private: SOCKET& conn; }; class tcpstream : public iostream { public: tcpstream(tcpbuf* tbuf) : iostream(tbuf), buf(tbuf) {} ~tcpstream() {} tcpbuf* rdbuf(void) const { return buf; } bool is_open() const { return true; } private: mutable tcpbuf* buf; };
Code
The following is a code posting for the implementation of std::iostream for sockets
on windows (it should be considered to be in the public domain).