处理socket描述符如文件描述符(fstream)? C ++ / Linux的

偶然发现,我可以读写套接字描述符。 我可以以某种方式(ab)使用fstream机制将数据输出到套接字描述符?

Solutions Collecting From Web of "处理socket描述符如文件描述符(fstream)? C ++ / Linux的"

标准文件流不支持使用文件描述符。 但是,I / O流类可以很容易地创建自己的抽象,从而可以创建自己的字符来源或目标。 魔术类是std::streambuf其职责是在适当的时候缓冲字符并读取或写入字符。 Nicolai Josuttis的“C ++标准库”详细描述了如何这样做(我在多年前为Nico贡献的基础)。 使用套接字进行读写的流缓冲区的简单实现如下所示:

 #include <algorithm> #include <iostream> #include <iterator> #include <streambuf> #include <cstddef> #include <unistd.h> class fdbuf : public std::streambuf { private: enum { bufsize = 1024 }; char outbuf_[bufsize]; char inbuf_[bufsize + 16 - sizeof(int)]; int fd_; public: typedef std::streambuf::traits_type traits_type; fdbuf(int fd); ~fdbuf(); void open(int fd); void close(); protected: int overflow(int c); int underflow(); int sync(); }; fdbuf::fdbuf(int fd) : fd_(-1) { this->open(fd); } fdbuf::~fdbuf() { this->close(); } void fdbuf::open(int fd) { this->close(); this->fd_ = fd; this->setg(this->inbuf_, this->inbuf_, this->inbuf_); this->setp(this->outbuf_, this->outbuf_ + bufsize - 1); } void fdbuf::close() { if (!(this->fd_ < 0)) { this->sync(); ::close(this->fd_); } } int fdbuf::overflow(int c) { if (!traits_type::eq_int_type(c, traits_type::eof())) { *this->pptr() = traits_type::to_char_type(c); this->pbump(1); } return this->sync() == -1 ? traits_type::eof() : traits_type::not_eof(c); } int fdbuf::sync() { if (this->pbase() != this->pptr()) { std::streamsize size(this->pptr() - this->pbase()); std::streamsize done(::write(this->fd_, this->outbuf_, size)); // The code below assumes that it is success if the stream made // some progress. Depending on the needs it may be more // reasonable to consider it a success only if it managed to // write the entire buffer and, eg, loop a couple of times // to try achieving this success. if (0 < done) { std::copy(this->pbase() + done, this->pptr(), this->pbase()); this->setp(this->pbase(), this->epptr()); this->pbump(size - done); } } return this->pptr() != this->epptr()? 0: -1; } int fdbuf::underflow() { if (this->gptr() == this->egptr()) { std::streamsize pback(std::min(this->gptr() - this->eback(), std::ptrdiff_t(16 - sizeof(int)))); std::copy(this->egptr() - pback, this->egptr(), this->eback()); int done(::read(this->fd_, this->eback() + pback, bufsize)); this->setg(this->eback(), this->eback() + pback, this->eback() + pback + std::max(0, done)); } return this->gptr() == this->egptr() ? traits_type::eof() : traits_type::to_int_type(*this->gptr()); } int main() { fdbuf inbuf(0); std::istream in(&inbuf); fdbuf outbuf(1); std::ostream out(&outbuf); std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(out)); }