summaryrefslogtreecommitdiff
path: root/libcult/examples/os/net/ipv4/datagram
diff options
context:
space:
mode:
authorJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
committerJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
commita15cf65c44d5c224169c32ef5495b68c758134b7 (patch)
tree3419f58fc8e1b315ba8171910ee044c5d467c162 /libcult/examples/os/net/ipv4/datagram
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'libcult/examples/os/net/ipv4/datagram')
-rw-r--r--libcult/examples/os/net/ipv4/datagram/client.cxx66
-rw-r--r--libcult/examples/os/net/ipv4/datagram/makefile55
-rw-r--r--libcult/examples/os/net/ipv4/datagram/protocol.hxx20
-rw-r--r--libcult/examples/os/net/ipv4/datagram/server.cxx123
4 files changed, 264 insertions, 0 deletions
diff --git a/libcult/examples/os/net/ipv4/datagram/client.cxx b/libcult/examples/os/net/ipv4/datagram/client.cxx
new file mode 100644
index 0000000..863fc25
--- /dev/null
+++ b/libcult/examples/os/net/ipv4/datagram/client.cxx
@@ -0,0 +1,66 @@
+// file : examples/os/net/ipv4/datagram/client.cxx
+// author : Boris Kolpackov <boris@kolpackov.net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/types.hxx>
+
+#include <cult/os/net/ipv4/address.hxx>
+#include <cult/os/net/ipv4/datagram-socket.hxx>
+
+#include <iostream>
+#include <unistd.h> // usleep
+
+#include "protocol.hxx"
+
+using std::cerr;
+using std::endl;
+
+using namespace Cult;
+using namespace OS::Net::IPv4;
+
+class Args {};
+
+Int
+main (Int argc, Char* argv[])
+{
+ try
+ {
+ if (argc < 2)
+ throw Args ();
+
+ Address addr (argv[1], 10000);
+
+ DatagramSocket socket;
+
+ Message msg;
+ msg.sn = 0;
+
+ cerr << "message size : " << sizeof (msg) << " bytes" << endl;
+ cerr << "send buffer : " << socket.send_buffer_size () << " bytes" << endl;
+
+ for (Index i = 0; i < payload_size; i++)
+ {
+ msg.payload[i] = i;
+ }
+
+ for (; msg.sn < message_count; msg.sn++)
+ {
+ socket.send (&msg, sizeof (msg), addr);
+
+ // ::usleep (10);
+ }
+
+ return 0;
+ }
+ catch (OS::Exception const& e)
+ {
+ cerr << "errno: " << strerror (e.code ()) << endl;
+ }
+ catch (Args const&)
+ {
+ cerr << "usage: client <IPv4 address>" << endl;
+ }
+
+ return 1;
+}
diff --git a/libcult/examples/os/net/ipv4/datagram/makefile b/libcult/examples/os/net/ipv4/datagram/makefile
new file mode 100644
index 0000000..2dc8e1b
--- /dev/null
+++ b/libcult/examples/os/net/ipv4/datagram/makefile
@@ -0,0 +1,55 @@
+# file : examples/os/net/ipv4/datagram/makefile
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2010 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+client_cxx_tun := client.cxx
+server_cxx_tun := server.cxx
+
+client_cxx_obj := $(addprefix $(out_base)/,$(client_cxx_tun:.cxx=.o))
+server_cxx_obj := $(addprefix $(out_base)/,$(server_cxx_tun:.cxx=.o))
+
+cxx_obj := $(client_cxx_obj) $(server_cxx_obj)
+cxx_od := $(cxx_obj:.o=.o.d)
+
+cult.l := $(out_root)/cult/cult.l
+cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options
+
+client := $(out_base)/client
+server := $(out_base)/server
+clean := $(out_base)/.clean
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(client) $(server)
+
+# Build.
+#
+
+$(client): $(client_cxx_obj) $(cult.l)
+$(server): $(server_cxx_obj) $(cult.l)
+
+$(cxx_obj) $(cxx_od): $(cult.l.cpp-options)
+
+$(call include-dep,$(cxx_od))
+
+
+# Clean.
+#
+$(clean): $(client).o.clean \
+ $(server).o.clean \
+ $(addsuffix .cxx.clean,$(cxx_obj)) \
+ $(addsuffix .cxx.clean,$(cxx_od))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/cult/makefile)
diff --git a/libcult/examples/os/net/ipv4/datagram/protocol.hxx b/libcult/examples/os/net/ipv4/datagram/protocol.hxx
new file mode 100644
index 0000000..0f418e8
--- /dev/null
+++ b/libcult/examples/os/net/ipv4/datagram/protocol.hxx
@@ -0,0 +1,20 @@
+// file : examples/os/net/ipv4/datagram/protocol.hxx
+// author : Boris Kolpackov <boris@kolpackov.net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef PROTOCOL_HXX
+#define PROTOCOL_HXX
+
+#include <cult/types.hxx>
+
+Cult::UnsignedShort const payload_size = 256;
+Cult::UnsignedLong const message_count = 100;
+
+struct Message
+{
+ Cult::UnsignedLong sn;
+ Cult::UnsignedShort payload[payload_size];
+};
+
+#endif // PROTOCOL_HXX
diff --git a/libcult/examples/os/net/ipv4/datagram/server.cxx b/libcult/examples/os/net/ipv4/datagram/server.cxx
new file mode 100644
index 0000000..e788056
--- /dev/null
+++ b/libcult/examples/os/net/ipv4/datagram/server.cxx
@@ -0,0 +1,123 @@
+// file : examples/os/net/ipv4/datagram/server.cxx
+// author : Boris Kolpackov <boris@kolpackov.net>
+// copyright : Copyright (c) 2005-2010 Boris Kolpackov
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/types.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <cult/os/net/ipv4/address.hxx>
+#include <cult/os/net/ipv4/datagram-socket.hxx>
+
+#include <iostream>
+#include <cstring> // memcmp
+
+#include "protocol.hxx"
+
+using std::cerr;
+using std::endl;
+
+using namespace Cult;
+using namespace OS::Net::IPv4;
+
+typedef Containers::Vector<Boolean> StatusList;
+
+Int
+main ()
+{
+ try
+ {
+ Address addr (INADDR_ANY, 10000);
+
+ DatagramSocket socket (addr);
+
+ Message expected_msg;
+ expected_msg.sn = 0;
+
+ for (UnsignedShort i = 0; i < payload_size; ++i)
+ {
+ expected_msg.payload[i] = i;
+ }
+
+ StatusList received (message_count, 0);
+ StatusList damaged (message_count, 0);
+ StatusList duplicate (message_count, 0);
+
+ Message msg;
+
+ while (true)
+ {
+ socket.recv (&msg, sizeof (msg));
+
+ if (received[msg.sn])
+ {
+ duplicate[msg.sn] = true;
+ }
+ else
+ {
+ received[msg.sn] = true;
+
+ if (std::memcmp (expected_msg.payload, msg.payload, payload_size) != 0)
+ {
+ damaged[msg.sn] = true;
+ }
+ }
+
+ if (msg.sn + 1 == message_count) break;
+ }
+
+ UnsignedLong lost_count (0), damaged_count (0), duplicate_count (0);
+
+ for (StatusList::Iterator i (received.begin ()), end (received.end ());
+ i != end;
+ ++i)
+ if (!*i) ++lost_count;
+
+ for (StatusList::Iterator i (damaged.begin ()), end (damaged.end ());
+ i != end;
+ ++i)
+ if (*i) ++damaged_count;
+
+ for (StatusList::Iterator i (duplicate.begin ()), end (duplicate.end ());
+ i != end;
+ ++i)
+ if (*i) ++duplicate_count;
+
+ cerr << "lost : " << lost_count << endl
+ << "damaged : " << damaged_count << endl
+ << "duplicate : " << duplicate_count << endl << endl;
+
+ if (lost_count != 0)
+ {
+ cerr << "lost message dump:" << endl;
+
+ UnsignedLong total = 0;
+
+ for (StatusList::Iterator
+ begin (received.begin ()), i (begin), end (received.end ());
+ i != end;)
+ {
+ if (!*i)
+ {
+ UnsignedLong count = 1;
+
+ for (StatusList::Iterator j = i + 1; j < end && !*j; j++, count++) ;
+
+ cerr << '\t' << i - begin << " : " << count << endl;
+
+ i += count;
+ total += count;
+ }
+ else
+ ++i;
+ }
+
+ if (total != lost_count)
+ cerr << "trouble" << endl;
+ }
+ }
+ catch (OS::Exception const& e)
+ {
+ cerr << "errno: " << e.code () << endl;
+ }
+}