// // // // // Lab. Calcolo II - Esempio di codice // // // // // // // // Example code: Simple C-socketlib based network buffer for use with the // "C++ in a nutshell" basic_networkbuf // (20060914 francesco.prelz@mi.infn.it) // #ifndef BASIC_NETWORKSTREAM_HPP_INCLUDED #define BASIC_NETWORKSTREAM_HPP_INCLUDED #include <iostream> #include <string> #include <sstream> #include <unistd.h> extern "C" { int SHLP_open_and_connect(const char *server, unsigned short port); int SHLP_listen(unsigned short port, int backlog); int SHLP_connect(int fd_socket, unsigned int in_timeout, char *caller_id, int caller_id_size); int SHLP_listen_and_connect(unsigned short port, unsigned int in_timeout, char *caller_id, int caller_id_size); } template <typename charT, typename traits = std::char_traits<char> > class basic_networkstream { public: typedef std::streampos pos_type; typedef charT char_type; basic_networkstream(); basic_networkstream(const char *address, std::ios_base::openmode mode); basic_networkstream(const char *address, const int port, std::ios_base::openmode mode); bool is_open() { return m_opened; } void open(int listen_sock, std::ios_base::openmode mode); void open(const char* address, std::ios_base::openmode mode); void open(const char* address, const int port, std::ios_base::openmode mode); void close(); bool good() { return m_good; } const std::string &caller() const { return m_caller; } pos_type tellg(); std::streamsize read(char_type *buffer, std::streamsize count); std::streamsize write(const char_type *buffer, std::streamsize count); std::streamsize gcount() { return m_gcount; } void sync(); int &timeout() { return m_timeout; }; private: int m_s; // The good ol' libC socket. bool m_good; bool m_opened; int m_timeout; std::string m_caller; std::streamsize m_gcount; std::streamsize m_tcount; }; template<typename charT, typename traits > basic_networkstream<charT, traits>::basic_networkstream() : m_good(false), m_opened(false), m_timeout(0) { } template<typename charT, typename traits > basic_networkstream<charT, traits>::basic_networkstream(const char *address, std::ios_base::openmode mode) : m_good(false), m_opened(false), m_timeout(0) { open(address,mode); } template<typename charT, typename traits > basic_networkstream<charT, traits>::basic_networkstream(const char *address, const int port, std::ios_base::openmode mode) : m_good(false), m_opened(false), m_timeout(0) { open(address,port,mode); } template<typename charT, typename traits > void basic_networkstream<charT, traits>::open(const char* address, std::ios_base::openmode mode) { // Try to figure out an address in the format ip:port. std::string addr_str(address); std::string::size_type colon_pos = addr_str.rfind(':'); if (colon_pos == std::string::npos) { m_good = false; return; } std::istringstream port_ss(addr_str.substr(colon_pos+1)); addr_str.erase(colon_pos); unsigned int port; port_ss >> port; if (port == 0 || port > 65535) { m_good = false; return; } return this->open(addr_str.c_str(), port); } template<typename charT, typename traits > void basic_networkstream<charT, traits>::open(const char* address, const int port, std::ios_base::openmode mode) { if (m_opened) { this->close(); } m_good = false; if (mode == std::ios::in) { char caller_c[512]; if ((m_s = SHLP_listen_and_connect(port, m_timeout, caller_c, sizeof(caller_c))) >= 0) { m_opened = true; m_good = true; m_caller = caller_c; } } else if (mode & std::ios::out) { if ((m_s = SHLP_open_and_connect(address, port)) >= 0) { m_opened = true; m_good = true; } } if (m_good) m_tcount = 0; return; } template<typename charT, typename traits > void basic_networkstream<charT, traits>::open(int listen_socket, std::ios_base::openmode mode) { if (m_opened) { this->close(); } m_good = false; if (mode & std::ios::in) { char caller_c[512]; if ((m_s = SHLP_connect(listen_socket, m_timeout, caller_c, sizeof(caller_c))) >= 0) { m_good = true; m_opened = true; m_caller = caller_c; } } if (m_good) m_tcount = 0; return; } template<typename charT, typename traits > void basic_networkstream<charT, traits>::close() { if (::close(m_s) < 0) m_good = false; else m_good = true; m_opened = false; } template<typename charT, typename traits > typename basic_networkstream<charT, traits>::pos_type basic_networkstream<charT, traits>::tellg() { return static_cast<typename basic_networkstream<charT, traits>::pos_type>(m_tcount); } template<typename charT, typename traits > std::streamsize basic_networkstream<charT, traits>::read(char_type *buffer, std::streamsize count) { std::streamsize ret; ret = ::read(m_s,buffer,count); if (ret < 0) m_good = false; else { m_tcount += ret; m_gcount = ret; } return ret; } template<typename charT, typename traits > std::streamsize basic_networkstream<charT, traits>::write(const char_type *buffer, std::streamsize count) { std::streamsize ret; ret = ::write(m_s,buffer,count); if (ret < 0) m_good = false; else m_tcount += ret; return ret; } template<typename charT, typename traits > void basic_networkstream<charT, traits>::sync() { // NOP on the network. } #endif // BASIC_NETWORKSTREAM_HPP_INCLUDED not defined