Add netcat example
authorMikko Rasa <tdb@tdb.fi>
Sat, 6 Aug 2011 16:24:36 +0000 (19:24 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 6 Aug 2011 16:24:36 +0000 (19:24 +0300)
.gitignore
Build
examples/netcat.cpp [new file with mode: 0644]

index e4bb400a25175cf2159eb25ee92917d847e85acf..bee94e59390ccc980fccc80e09dee5755da6aa81 100644 (file)
@@ -5,6 +5,7 @@
 /libmspnet.a
 /libmspnet.so
 /mspnet.pc
+/netcat
 /pc-32-windows
 /release
 /temp
diff --git a/Build b/Build
index dc20f0e9f6ba52944e6cab719a0184b27319c44a..899274bc948e1c1a7e0c53367c5d7982fc610068 100644 (file)
--- a/Build
+++ b/Build
@@ -20,4 +20,13 @@ package "mspnet"
                source "source";
                install true;
        };
+
+       program "netcat"
+       {
+               source "examples/netcat.cpp";
+               build_info
+               {
+                       library "mspnet";
+               };
+       };
 };
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);
+}