#include "SocketStream.h" #include "BaseException.h" #include #include #include #include #include #include #include #include #include using namespace std; namespace FD { const int network_socket::BROADCAST_TYPE = 0; const int network_socket::TCP_STREAM_TYPE = 1; #define FLOWDESIGNER_IDENT_STRLEN 8 #define FLOWDESIGNER_IDENT "OVERFLOW" #define FLOWDESIGNER_BROADCAST_IP "255.255.255.255" network_socket::network_socket(int type, int port) : m_read_socket(0) , m_listen_socket(0) , m_write_socket(0), m_port(port), m_type(type) { switch (m_type) { case BROADCAST_TYPE: init_broadcast(); break; case TCP_STREAM_TYPE: break; default: throw new GeneralException("Unknown packet type",__FILE__,__LINE__); break; } } network_socket::~network_socket() { //shutting down communication shutdown(); } void network_socket::printOn (ostream &out) const { out<<""<h_addr_list[0], entp->h_length); serverp.sin_port = htons(m_port); /* * Create the INET socket. * */ if((m_listen_socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("network_socket::init_tcp_stream : call to socket() failed; socket not created."); throw new GeneralException("network_socket::init_tcp_stream : socket not created.",__FILE__,__LINE__); } /* * let's say that our process should get the SIGIO's when it's * readable */ //Carle : Remove set ownership, error on my system /* if(fcntl(m_listen_socket, F_SETOWN, getpid()) == -1) { perror("network_socket::init_tcp_stream : call to fcntl() failed while setting socket " "pid ownership; socket not created."); shutdown(); throw new GeneralException("network_socket::init_tcp_stream : could not change ownership of the socket." ,__FILE__,__LINE__); } */ /* * get the current access flags */ if((flags = fcntl(m_listen_socket, F_GETFL)) == -1) { perror("network_socket::init_tcp_stream : call to fcntl failed while getting socket " "access flags; socket not created."); shutdown(); throw new GeneralException("network_socket::init_tcp_stream : could not get flags of the socket." ,__FILE__,__LINE__); } if(!blocking) { /* * OR the current flags with * O_NONBLOCK (so we won't block), and write them back */ if(fcntl(m_listen_socket, F_SETFL, flags | O_NONBLOCK ) == -1) { perror("network_socket::init_tcp_stream : call to :fcntl() failed while setting socket " "access flags; socket not created."); shutdown(); throw new GeneralException("network_socket::init_tcp_stream : could not set flags (O_NONBLOCK) of the socket." ,__FILE__,__LINE__); } }//non blocking /* make sure we can reuse the port soon after */ if(setsockopt(m_listen_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one))) { perror("network_socket::init_tcp_stream : setsockopt(2) failed"); throw new GeneralException("network_socket::init_tcp_stream : setsocktopt failed." ,__FILE__,__LINE__); } /* * Bind it to the port indicated * INADDR_ANY indicates that any network interface (IP address) * for the local host may be used (presumably the OS will choose the * right * one). * * Specifying sin_port = 0 would allow the system to choose the port. */ serverp.sin_family = PF_INET; serverp.sin_addr.s_addr = INADDR_ANY; if(bind(m_listen_socket, (struct sockaddr*) &serverp, sizeof(serverp)) == -1) { perror ("network_socket::init_tcp_stream : bind() failed; socket not created."); shutdown(); throw new GeneralException("network_socket::init_tcp_stream : bind failed." ,__FILE__,__LINE__); } cerr<<"init_tcp_stream done!"<h_addr_list[0], entp->h_length); //setting port server.sin_port = htons(m_port); /* make our socket (and leave it blocking) */ if((m_write_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("network_socket::connect(): socket() failed"); throw new GeneralException("network_socket::connect connect() failed",__FILE__,__LINE__); } //same socket for read & write m_read_socket = m_write_socket; /* * hook it up */ if(connect(m_write_socket, (struct sockaddr*)&server, sizeof(server)) == -1) { perror("network_socket::connect(): connect() failed"); shutdown(); throw new GeneralException("network_socket::connect(): connect() failed",__FILE__,__LINE__); } // CC- Disable banner features. 01/12/2003 // /* // * read the banner from the server // */ // if((numread = recv_packet(&banner[0],FLOWDESIGNER_IDENT_STRLEN)) != FLOWDESIGNER_IDENT_STRLEN) { // perror("network_socket::connect(): read() failed"); // shutdown(); // throw new GeneralException("network_socket::connect(): read() failed",__FILE__,__LINE__); // } // // /* // * verify the banner (if it contains "OVERFLOW") // */ // // if (banner[0] != 'O' || banner[1] != 'V' || banner[2] != 'E' || banner[3] != 'R' || // banner[4] != 'F' || banner[5] != 'L' || banner[6] != 'O' || banner[7] != 'W') { // shutdown(); // throw new GeneralException("network_socket::connect() does not contain the banner",__FILE__,__LINE__); // } } /****************************************************************************** Stream part! *******************************************************************************/ socket_streambuf::socket_streambuf(int type, int port) : network_socket(type,port) , takeFromBuf(false) { } int socket_streambuf::overflow(int c) { send_packet((unsigned char*) &c, 1); //FIXME: Find EOF? return 0; } streamsize socket_streambuf::xsputn(const char *s, streamsize n) { return send_packet((unsigned char*) s, (size_t) n); } int socket_streambuf::uflow() { if (takeFromBuf) { takeFromBuf = false; return charBuf; } else { recv_packet((unsigned char*) &charBuf, 1); return charBuf; } } int socket_streambuf::underflow() { if (takeFromBuf) { return charBuf; } else { recv_packet((unsigned char*) &charBuf, 1); takeFromBuf = true; return charBuf; } } int socket_streambuf::pbackfail(int c) { if (!takeFromBuf) { if (c != EOF) charBuf = c; takeFromBuf = true; return charBuf; } else { return EOF; } } streamsize socket_streambuf::xsgetn(char *s, streamsize n) { return recv_packet((unsigned char*) s, (size_t) n); } }//namespace FD