]> git.tdb.fi Git - libs/net.git/blob - examples/netcat.cpp
Add a dynamic receiver class for more flexible packet handling
[libs/net.git] / examples / netcat.cpp
1 #include <msp/core/application.h>
2 #include <msp/core/getopt.h>
3 #include <msp/core/refptr.h>
4 #include <msp/io/console.h>
5 #include <msp/io/eventdispatcher.h>
6 #include <msp/net/streamserversocket.h>
7 #include <msp/net/streamsocket.h>
8 #include <msp/net/resolve.h>
9
10 using namespace std;
11 using namespace Msp;
12
13 class NetCat: public RegisteredApplication<NetCat>
14 {
15 private:
16         bool ipv6;
17         bool listen;
18         Net::StreamServerSocket *server_sock;
19         Net::StreamSocket *sock;
20         IO::EventDispatcher event_disp;
21
22 public:
23         NetCat(int, char **);
24
25 private:
26         virtual void tick();
27         void net_data_available();
28         void console_data_available();
29 };
30
31 NetCat::NetCat(int argc, char **argv):
32         ipv6(false),
33         listen(false),
34         server_sock(0),
35         sock(0)
36 {
37         string host_name;
38
39         GetOpt getopt;
40         getopt.add_option('6', "ipv6",   ipv6,   GetOpt::NO_ARG);
41         getopt.add_option('l', "listen", listen, GetOpt::NO_ARG);
42         getopt.add_argument("host", host_name, GetOpt::REQUIRED_ARG);
43         getopt(argc, argv);
44
45         RefPtr<Net::SockAddr> addr = Net::resolve(host_name, (ipv6 ? Net::INET6 : Net::INET));
46         if(!listen)
47         {
48                 sock = new Net::StreamSocket(addr->get_family());
49                 sock->connect(*addr);
50                 event_disp.add(*sock);
51                 sock->signal_data_available.connect(sigc::mem_fun(this, &NetCat::net_data_available));
52         }
53         else
54         {
55                 server_sock = new Net::StreamServerSocket(addr->get_family());
56                 server_sock->listen(*addr);
57                 event_disp.add(*server_sock);
58                 server_sock->signal_data_available.connect(sigc::mem_fun(this, &NetCat::net_data_available));
59         }
60
61         event_disp.add(IO::cin);
62         IO::cin.signal_data_available.connect(sigc::mem_fun(this, &NetCat::console_data_available));
63 }
64
65 void NetCat::tick()
66 {
67         event_disp.tick();
68         if(server_sock && sock)
69         {
70                 delete server_sock;
71                 server_sock = 0;
72         }
73 }
74
75 void NetCat::net_data_available()
76 {
77         if(server_sock)
78         {
79                 sock = server_sock->accept();
80                 event_disp.add(*sock);
81                 sock->signal_data_available.connect(sigc::mem_fun(this, &NetCat::net_data_available));
82         }
83         else
84         {
85                 char buf[1024];
86                 unsigned len = sock->read(buf, sizeof(buf));
87                 IO::cout.write(buf, len);
88         }
89 }
90
91 void NetCat::console_data_available()
92 {
93         char buf[1024];
94         unsigned len = IO::cin.read(buf, sizeof(buf));
95         if(sock)
96                 sock->write(buf, len);
97 }