]> git.tdb.fi Git - libs/net.git/blobdiff - examples/netcat.cpp
Add netcat example
[libs/net.git] / examples / netcat.cpp
diff --git a/examples/netcat.cpp b/examples/netcat.cpp
new file mode 100644 (file)
index 0000000..2532959
--- /dev/null
@@ -0,0 +1,98 @@
+#include <msp/core/application.h>
+#include <msp/core/getopt.h>
+#include <msp/core/refptr.h>
+#include <msp/io/console.h>
+#include <msp/io/eventdispatcher.h>
+#include <msp/net/streamlistensocket.h>
+#include <msp/net/streamsocket.h>
+#include <msp/net/resolve.h>
+
+using namespace std;
+using namespace Msp;
+
+class NetCat: public RegisteredApplication<NetCat>
+{
+private:
+       bool ipv6;
+       bool listen;
+       Net::StreamListenSocket *server_sock;
+       Net::StreamSocket *sock;
+       IO::EventDispatcher event_disp;
+
+public:
+       NetCat(int, char **);
+
+private:
+       virtual void tick();
+       void net_data_available();
+       void console_data_available();
+};
+
+NetCat::NetCat(int argc, char **argv):
+       ipv6(false),
+       listen(false),
+       server_sock(0),
+       sock(0)
+{
+       GetOpt getopt;
+       getopt.add_option('6', "ipv6",   ipv6,   GetOpt::NO_ARG);
+       getopt.add_option('l', "listen", listen, GetOpt::NO_ARG);
+       getopt(argc, argv);
+
+       const vector<string> &args = getopt.get_args();
+       if(args.empty())
+               throw usage_error("host argument missing");
+
+       RefPtr<Net::SockAddr> addr = Net::resolve(args.front(), (ipv6 ? Net::INET6 : Net::INET));
+       if(!listen)
+       {
+               sock = new Net::StreamSocket(addr->get_family());
+               sock->connect(*addr);
+               event_disp.add(*sock);
+               sock->signal_data_available.connect(sigc::mem_fun(this, &NetCat::net_data_available));
+       }
+       else
+       {
+               server_sock = new Net::StreamListenSocket(addr->get_family());
+               server_sock->listen(*addr);
+               event_disp.add(*server_sock);
+               server_sock->signal_data_available.connect(sigc::mem_fun(this, &NetCat::net_data_available));
+       }
+
+       event_disp.add(IO::cin);
+       IO::cin.signal_data_available.connect(sigc::mem_fun(this, &NetCat::console_data_available));
+}
+
+void NetCat::tick()
+{
+       event_disp.tick();
+       if(server_sock && sock)
+       {
+               delete server_sock;
+               server_sock = 0;
+       }
+}
+
+void NetCat::net_data_available()
+{
+       if(server_sock)
+       {
+               sock = server_sock->accept();
+               event_disp.add(*sock);
+               sock->signal_data_available.connect(sigc::mem_fun(this, &NetCat::net_data_available));
+       }
+       else
+       {
+               char buf[1024];
+               unsigned len = sock->read(buf, sizeof(buf));
+               IO::cout.write(buf, len);
+       }
+}
+
+void NetCat::console_data_available()
+{
+       char buf[1024];
+       unsigned len = IO::cin.read(buf, sizeof(buf));
+       if(sock)
+               sock->write(buf, len);
+}