# to unbundle, sh this file echo ClientSocket.cpp 1>&2 cat >ClientSocket.cpp <<'End of ClientSocket.cpp' // Implementation of the ClientSocket class #include "ClientSocket.h" #include "SocketException.h" ClientSocket::ClientSocket ( std::string host, int port ) { if ( ! Socket::create() ) { throw SocketException ( "Could not create client socket." ); } if ( ! Socket::connect ( host, port ) ) { throw SocketException ( "Could not bind to port." ); } } const ClientSocket& ClientSocket::operator << ( const std::string& s ) const { if ( ! Socket::send ( s ) ) { throw SocketException ( "Could not write to socket." ); } return *this; } const ClientSocket& ClientSocket::operator >> ( std::string& s ) const { if ( ! Socket::recv ( s ) ) { throw SocketException ( "Could not read from socket." ); } return *this; } End of ClientSocket.cpp echo ClientSocket.h 1>&2 cat >ClientSocket.h <<'End of ClientSocket.h' // Definition of the ClientSocket class #ifndef ClientSocket_class #define ClientSocket_class #include "Socket.h" class ClientSocket : private Socket { public: ClientSocket ( std::string host, int port ); virtual ~ClientSocket(){}; const ClientSocket& operator << ( const std::string& ) const; const ClientSocket& operator >> ( std::string& ) const; }; #endif End of ClientSocket.h echo Makefile 1>&2 cat >Makefile <<'End of Makefile' # Makefile for the socket programming example # simple_server_objects = ServerSocket.o Socket.o simple_server_main.o simple_client_objects = ClientSocket.o Socket.o simple_client_main.o all : simple_server simple_client simple_server: $(simple_server_objects) g++ -o simple_server $(simple_server_objects) simple_client: $(simple_client_objects) g++ -o simple_client $(simple_client_objects) Socket: Socket.cpp ServerSocket: ServerSocket.cpp ClientSocket: ClientSocket.cpp simple_server_main: simple_server_main.cpp simple_client_main: simple_client_main.cpp clean: rm -f *.o simple_server simple_clientEnd of Makefile echo ServerSocket.cpp 1>&2 cat >ServerSocket.cpp <<'End of ServerSocket.cpp' // Implementation of the ServerSocket class #include "ServerSocket.h" #include "SocketException.h" ServerSocket::ServerSocket ( int port ) { if ( ! Socket::create() ) { throw SocketException ( "Could not create server socket." ); } if ( ! Socket::bind ( port ) ) { throw SocketException ( "Could not bind to port." ); } if ( ! Socket::listen() ) { throw SocketException ( "Could not listen to socket." ); } } ServerSocket::~ServerSocket() { } const ServerSocket& ServerSocket::operator << ( const std::string& s ) const { if ( ! Socket::send ( s ) ) { throw SocketException ( "Could not write to socket." ); } return *this; } const ServerSocket& ServerSocket::operator >> ( std::string& s ) const { if ( ! Socket::recv ( s ) ) { throw SocketException ( "Could not read from socket." ); } return *this; } void ServerSocket::accept ( ServerSocket& sock ) { if ( ! Socket::accept ( sock ) ) { throw SocketException ( "Could not accept socket." ); } } End of ServerSocket.cpp echo ServerSocket.h 1>&2 cat >ServerSocket.h <<'End of ServerSocket.h' // Definition of the ServerSocket class #ifndef ServerSocket_class #define ServerSocket_class #include "Socket.h" class ServerSocket : private Socket { public: ServerSocket ( int port ); ServerSocket (){}; virtual ~ServerSocket(); const ServerSocket& operator << ( const std::string& ) const; const ServerSocket& operator >> ( std::string& ) const; void accept ( ServerSocket& ); }; #endif End of ServerSocket.h echo Socket.cpp 1>&2 cat >Socket.cpp <<'End of Socket.cpp' // Implementation of the Socket class. #include "Socket.h" #include "string.h" #include #include #include Socket::Socket() : m_sock ( -1 ) { memset ( &m_addr, 0, sizeof ( m_addr ) ); } Socket::~Socket() { if ( is_valid() ) ::close ( m_sock ); } bool Socket::create() { m_sock = socket ( AF_INET, SOCK_STREAM, 0 ); if ( ! is_valid() ) return false; // TIME_WAIT - argh int on = 1; if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) return false; return true; } bool Socket::bind ( const int port ) { if ( ! is_valid() ) { return false; } m_addr.sin_family = AF_INET; m_addr.sin_addr.s_addr = INADDR_ANY; m_addr.sin_port = htons ( port ); int bind_return = ::bind ( m_sock, ( struct sockaddr * ) &m_addr, sizeof ( m_addr ) ); if ( bind_return == -1 ) { return false; } return true; } bool Socket::listen() const { if ( ! is_valid() ) { return false; } int listen_return = ::listen ( m_sock, MAXCONNECTIONS ); if ( listen_return == -1 ) { return false; } return true; } bool Socket::accept ( Socket& new_socket ) const { int addr_length = sizeof ( m_addr ); new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length ); if ( new_socket.m_sock <= 0 ) return false; else return true; } bool Socket::send ( const std::string s ) const { int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL ); if ( status == -1 ) { return false; } else { return true; } } int Socket::recv ( std::string& s ) const { char buf [ MAXRECV + 1 ]; s = ""; memset ( buf, 0, MAXRECV + 1 ); int status = ::recv ( m_sock, buf, MAXRECV, 0 ); if ( status == -1 ) { std::cout << "status == -1 errno == " << errno << " in Socket::recv\n"; return 0; } else if ( status == 0 ) { return 0; } else { s = buf; return status; } } bool Socket::connect ( const std::string host, const int port ) { if ( ! is_valid() ) return false; m_addr.sin_family = AF_INET; m_addr.sin_port = htons ( port ); int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr ); if ( errno == EAFNOSUPPORT ) return false; status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) ); if ( status == 0 ) return true; else return false; } void Socket::set_non_blocking ( const bool b ) { int opts; opts = fcntl ( m_sock, F_GETFL ); if ( opts < 0 ) { return; } if ( b ) opts = ( opts | O_NONBLOCK ); else opts = ( opts & ~O_NONBLOCK ); fcntl ( m_sock, F_SETFL,opts ); } End of Socket.cpp echo Socket.h 1>&2 cat >Socket.h <<'End of Socket.h' // Definition of the Socket class #ifndef Socket_class #define Socket_class #include #include #include #include #include #include #include const int MAXHOSTNAME = 200; const int MAXCONNECTIONS = 5; const int MAXRECV = 500; class Socket { public: Socket(); virtual ~Socket(); // Server initialization bool create(); bool bind ( const int port ); bool listen() const; bool accept ( Socket& ) const; // Client initialization bool connect ( const std::string host, const int port ); // Data Transimission bool send ( const std::string ) const; int recv ( std::string& ) const; void set_non_blocking ( const bool ); bool is_valid() const { return m_sock != -1; } private: int m_sock; sockaddr_in m_addr; }; #endif End of Socket.h echo SocketException.h 1>&2 cat >SocketException.h <<'End of SocketException.h' // SocketException class #ifndef SocketException_class #define SocketException_class #include class SocketException { public: SocketException ( std::string s ) : m_s ( s ) {}; ~SocketException (){}; std::string description() { return m_s; } private: std::string m_s; }; #endif End of SocketException.h echo Test 1>&2 cat >Test <<'End of Test' cat TESTFILE | simple_client End of Test echo Test2 1>&2 cat >Test2 <<'End of Test2' mkTorus -d 2 2 | simple_client End of Test2 echo Test3 1>&2 cat >Test3 <<'End of Test3' man ls | grep -n the | simple_client End of Test3 echo Test4 1>&2 cat >Test4 <<'End of Test4' cat zigzag.txt | simple_client Test4 End of Test4 echo simple_client_main.cpp 1>&2 cat >simple_client_main.cpp <<'End of simple_client_main.cpp' #include "ClientSocket.h" #include "SocketException.h" #include #include int main ( int argc, int argv[] ) { try { // ClientSocket client_socket ( "localhost", 30000 ); ClientSocket client_socket ( "192.168.1.10", 30000 ); char text_line[255]; try { while (cin.getline(text_line, 255)) { client_socket << text_line << "\n"; cout << text_line << "\n"; } } catch ( SocketException& ) {} } catch ( SocketException& e ) { std::cout << "Exception was caught:" << e.description() << "\n"; } return 0; } End of simple_client_main.cpp echo simple_server_main.cpp 1>&2 cat >simple_server_main.cpp <<'End of simple_server_main.cpp' #include "ServerSocket.h" #include "SocketException.h" #include int main ( int argc, int argv[] ) { try { // Create the socket ServerSocket server ( 30000 ); while ( true ) { ServerSocket new_sock; server.accept ( new_sock ); try { while ( true ) { std::string data; new_sock >> data; std::cout << data; } } catch ( SocketException& ) {} } } catch ( SocketException& e ) { std::cout << "Exception was caught:" << e.description() << "\nExiting.\n"; } return 0; } End of simple_server_main.cpp