changeset 497:8b161d143975

Socket: put back examples that were removed by mistake
author David Demelier <markand@malikania.fr>
date Mon, 14 Dec 2015 09:41:28 +0100
parents 3c783cf492ab
children 1c0342584e55
files modules/sockets/examples/ElapsedTimer.cpp modules/sockets/examples/ElapsedTimer.h modules/sockets/examples/blocking-accept.cpp modules/sockets/examples/blocking-connect.cpp modules/sockets/examples/non-blocking-accept.cpp modules/sockets/examples/non-blocking-connect.cpp modules/sockets/examples/stream-client.cpp modules/sockets/examples/stream-server.cpp modules/sockets/examples/test.crt modules/sockets/examples/test.key
diffstat 10 files changed, 531 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/ElapsedTimer.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,60 @@
+/*
+ * ElapsedTimer.cpp -- measure elapsed time
+ *
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ElapsedTimer.h"
+
+using std::chrono::duration_cast;
+using std::chrono::high_resolution_clock;
+using std::chrono::milliseconds;
+
+ElapsedTimer::ElapsedTimer() noexcept
+{
+	m_last = high_resolution_clock::now();
+}
+
+void ElapsedTimer::pause() noexcept
+{
+	/*
+	 * When we put the timer on pause, do not forget to set the already
+	 * elapsed time.
+	 */
+	(void)elapsed();
+	m_paused = true;
+}
+
+void ElapsedTimer::restart() noexcept
+{
+	m_paused = false;
+	m_last = high_resolution_clock::now();
+}
+
+void ElapsedTimer::reset() noexcept
+{
+	m_elapsed = 0;
+	m_last = high_resolution_clock::now();
+}
+
+unsigned ElapsedTimer::elapsed() noexcept
+{
+	if (!m_paused) {
+		m_elapsed += duration_cast<milliseconds>(high_resolution_clock::now() - m_last).count();
+		m_last = high_resolution_clock::now();
+	}
+
+	return m_elapsed;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/ElapsedTimer.h	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,77 @@
+/*
+ * ElapsedTimer.h -- measure elapsed time
+ *
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _ELAPSED_TIMER_H_
+#define _ELAPSED_TIMER_H_
+
+/**
+ * @file ElapsedTimer.h
+ * @brief Measure elapsed time
+ */
+
+#include <chrono>
+
+/**
+ * @class ElapsedTimer
+ * @brief Measure elapsed time
+ *
+ * This class provides an abstraction to measure elapsed time since the
+ * construction of the object.
+ *
+ * It uses std::chrono::high_resolution_clock for more precision and uses
+ * milliseconds only.
+ */
+class ElapsedTimer {
+public:
+	using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;
+
+private:
+	TimePoint m_last;
+	bool m_paused{false};
+	unsigned m_elapsed{0};
+
+public:
+	/**
+	 * Construct the elapsed timer, start counting.
+	 */
+	ElapsedTimer() noexcept;
+
+	/**
+	 * Put the timer on pause, the already elapsed time is stored.
+	 */
+	void pause() noexcept;
+
+	/**
+	 * Restart the timer, does not reset it.
+	 */
+	void restart() noexcept;
+
+	/**
+	 * Reset the timer to 0.
+	 */
+	void reset() noexcept;
+
+	/**
+	 * Get the number of elapsed milliseconds.
+	 *
+	 * @return the milliseconds
+	 */
+	unsigned elapsed() noexcept;
+};
+
+#endif // !_ELAPSED_TIMER_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/blocking-accept.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,52 @@
+/*
+ * blocking-accept.cpp -- example of blocking accept
+ *
+ * Options:
+ *   - WITH_PORT (int), the port to use (default: 16000)
+ *   - WITH_TIMEOUT (int), number of seconds before giving up (default: 60)
+ *   - WITH_SSL (bool), true to test with SSL (default: false)
+ */
+
+#include <iostream>
+
+#include "Sockets.h"
+
+#if !defined(WITH_PORT)
+#  define WITH_PORT 16000
+#endif
+
+#if !defined(WITH_TIMEOUT)
+#  define WITH_TIMEOUT 60
+#endif
+
+int main()
+{
+#if defined(WITH_SSL)
+	net::SocketTls<net::address::Ip> master;
+	net::SocketTls<net::address::Ip> client{net::Invalid};
+#else
+	net::SocketTcp<net::address::Ip> master;
+	net::SocketTcp<net::address::Ip> client{net::Invalid};
+#endif
+
+	net::Listener<> listener;
+
+	try {
+		master.set(net::option::SockReuseAddress{true});
+		master.bind(net::address::Ip{"*", WITH_PORT});
+		master.listen();
+
+		listener.set(master.handle(), net::Condition::Readable);
+		listener.wait(std::chrono::seconds(WITH_TIMEOUT));
+
+		client = master.accept(nullptr);
+	} catch (const net::Error &error) {
+		std::cerr << "error: " << error.what() << std::endl;
+		std::exit(1);
+	}
+
+	std::cout << "Client successfully accepted!" << std::endl;
+
+	return 0;	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/blocking-connect.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * blocking-connect.cpp -- example of blocking connect
+ *
+ * Options:
+ *   - WITH_HOST (string literal), the host to try (default: "malikania.fr")
+ *   - WITH_PORT (int), the port to use (default: 80)
+ *   - WITH_TIMEOUT (int), number of seconds before giving up (default: 30)
+ *   - WITH_SSL (bool), true to test with SSL (default: false)
+ */
+
+#include <iostream>
+
+#if !defined(WITH_HOST)
+#  define WITH_HOST "malikania.fr"
+#endif
+
+#if !defined(WITH_PORT)
+#  define WITH_PORT 80
+#endif
+
+#if !defined(WITH_TIMEOUT)
+#  define WITH_TIMEOUT 30
+#endif
+
+#include "ElapsedTimer.h"
+#include "Sockets.h"
+
+int main()
+{
+#if defined(WITH_SSL)
+	net::SocketTls<net::address::Ip> socket;
+#else
+	net::SocketTcp<net::address::Ip> socket;
+#endif
+
+	try {
+		std::cout << "Trying to connect to " << WITH_HOST << ":" << WITH_PORT << std::endl;
+		socket.connect(net::address::Ip{WITH_HOST, WITH_PORT});
+	} catch (const net::Error &error) {
+		std::cerr << "error: " << error.what() << std::endl;
+		std::exit(1);
+	}
+
+	if (socket.state() == net::State::Connected) {
+		std::cout << "Successfully connected!" << std::endl;
+	}
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/non-blocking-accept.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,72 @@
+/*
+ * non-blocking-accept.cpp -- example of total non-blocking accept
+ *
+ * Options:
+ *   - WITH_PORT (int), the port to use (default: 16000)
+ *   - WITH_TIMEOUT (int), number of seconds before giving up (default: 60)
+ *   - WITH_SSL (bool), true to test with SSL (default: false)
+ */
+
+#include <iostream>
+
+#include "ElapsedTimer.h"
+#include "Sockets.h"
+
+#if !defined(WITH_PORT)
+#  define WITH_PORT 16000
+#endif
+
+#if !defined(WITH_TIMEOUT)
+#  define WITH_TIMEOUT 60
+#endif
+
+int main()
+{
+#if defined(WITH_SSL)
+	net::SocketTls<net::address::Ip> master;
+	net::SocketTls<net::address::Ip> client{net::Invalid};
+#else
+	net::SocketTcp<net::address::Ip> master;
+	net::SocketTcp<net::address::Ip> client{net::Invalid};
+#endif
+
+	net::Listener<> listener;
+	ElapsedTimer timer;
+
+	// 1. Create the master socket for listening.
+	try {
+		master.set(net::option::SockReuseAddress{true});
+		master.set(net::option::SockBlockMode{false});
+		master.bind(net::address::Ip{"*", WITH_PORT});
+		master.listen();
+	} catch (const net::Error &error) {
+		std::cerr << "error: " << error.what() << std::endl;
+		std::exit(1);
+	}
+
+	while (client.state() != net::State::Accepted && timer.elapsed() < (WITH_TIMEOUT * 1000)) {
+		try {
+			if (client.state() == net::State::Closed) {
+				// 2. Wait for a pre-accept process.
+				listener.set(master.handle(), net::Condition::Readable);
+				listener.wait(std::chrono::seconds(WITH_TIMEOUT));
+				client = master.accept(nullptr);
+				client.set(net::option::SockBlockMode{false});
+				listener.remove(master.handle());
+			} else {
+				// 3. Wait for the accept process to complete.
+				listener.remove(client.handle());
+				listener.set(client.handle(), client.condition());
+				listener.wait(std::chrono::seconds(WITH_TIMEOUT));
+				client.accept();
+			}
+		} catch (const net::Error &error) {
+			std::cerr << error.function() << ": " << error.what() << std::endl;
+			std::exit(1);
+		}
+	}
+
+	std::cout << "Client successfully accepted!" << std::endl;
+
+	return 0;	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/non-blocking-connect.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,66 @@
+/*
+ * non-blocking-connect.cpp -- example of non blocking connect
+ *
+ * Options:
+ *   - WITH_HOST (string literal), the host to try (default: "malikania.fr")
+ *   - WITH_PORT (int), the port to use (default: 80)
+ *   - WITH_TIMEOUT (int), number of seconds before giving up (default: 30)
+ *   - WITH_SSL (bool), true to test with SSL (default: false)
+ */
+
+#include <iostream>
+
+#if !defined(WITH_HOST)
+#  define WITH_HOST "malikania.fr"
+#endif
+
+#if !defined(WITH_PORT)
+#  define WITH_PORT 80
+#endif
+
+#if !defined(WITH_TIMEOUT)
+#  define WITH_TIMEOUT 30
+#endif
+
+#include "ElapsedTimer.h"
+#include "Sockets.h"
+
+int main()
+{
+#if defined(WITH_SSL)
+	net::SocketTls<net::address::Ip> socket;
+#else
+	net::SocketTcp<net::address::Ip> socket;
+#endif
+
+	net::Listener<> listener;
+	ElapsedTimer timer;
+
+	// 1. Set to non-blocking.
+	socket.set(net::option::SockBlockMode{false});
+
+	try {
+		std::cout << "Trying to connect to " << WITH_HOST << ":" << WITH_PORT << std::endl;
+
+		// 2. Initial connection process.
+		socket.connect(net::address::Ip{WITH_HOST, WITH_PORT});
+
+		while (socket.state() != net::State::Connected) {
+			listener.remove(socket.handle());
+
+			// 2. Now complete by waiting for the appropriate condition.
+			listener.set(socket.handle(), socket.condition());
+			listener.wait(std::chrono::seconds(WITH_TIMEOUT));
+			socket.connect();
+		}
+	} catch (const net::Error &error) {
+		std::cerr << "error: " << error.what() << std::endl;
+		std::exit(1);
+	}
+
+	if (socket.state() == net::State::Connected) {
+		std::cout << "Successfully connected!" << std::endl;
+	}
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/stream-client.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,66 @@
+/*
+ * stream-server -- example of stream server
+ *
+ * Options:
+ *   - WITH_PORT (int) which port to use (default: 12000)
+ *   - WITH_HOST (string literal) which host to connect (default: "localhost")
+ *   - WITH_SSL (bool) true to use SSL (default: false)
+ */
+
+#include <iostream>
+
+#include "Sockets.h"
+
+#if !defined(WITH_PORT)
+#  define WITH_PORT 12000
+#endif
+
+#if !defined(WITH_HOST)
+#  define WITH_HOST "localhost"
+#endif
+
+#if defined(WITH_SSL)
+using Client = net::StreamClient<net::address::Ip, net::protocol::Tls>;
+#else
+using Client = net::StreamClient<net::address::Ip, net::protocol::Tcp>;
+#endif
+
+int main()
+{
+	Client client;
+
+	/*
+	 * Unfortunately at the moment the socket state is not changed, this will be done
+	 * in the future.
+	 */
+	bool connected{true};
+
+	client.setConnectionHandler([&] () {
+		std::cout << "client: successfully connected" << std::endl;
+		client.send("Hello world!");
+	});
+	client.setDisconnectionHandler([&] () {
+		std::cout << "client: disconnected" << std::endl;
+		connected = false;
+	});
+	client.setErrorHandler([&] (const net::Error &error) {
+		std::cout << "client: error: " << error.function() << ": " << error.what() << std::endl;
+		connected = false;
+	});
+	client.setReadHandler([] (const std::string &data) {
+		std::cout << "client: received: " << data << std::endl;
+	});
+	client.setWriteHandler([] (const std::string &data) {
+		std::cout << "client: sent: " << data << std::endl;
+	});
+
+	client.connect(net::address::Ip{WITH_HOST, WITH_PORT});
+
+	while (connected) {
+		client.poll();
+	}
+
+	std::cout << "client: exiting" << std::endl;
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/stream-server.cpp	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * stream-server -- example of stream server
+ *
+ * Options:
+ *   - WITH_PORT (int) which port to use (default: 12000)
+ *   - WITH_SSL (bool) true to use SSL (default: false)
+ */
+
+#include <iostream>
+
+#include "Sockets.h"
+
+#if !defined(WITH_PORT)
+#  define WITH_PORT 12000
+#endif
+
+#if defined(WITH_SSL)
+using Server = net::StreamServer<net::address::Ip, net::protocol::Tls>;
+using Connection = net::StreamConnection<net::address::Ip, net::protocol::Tls>;
+#else
+using Server = net::StreamServer<net::address::Ip, net::protocol::Tcp>;
+using Connection = net::StreamConnection<net::address::Ip, net::protocol::Tcp>;
+#endif
+
+int main()
+{
+#if defined(WITH_SSL)
+	net::protocol::Tls protocol;
+
+	protocol.setVerify(false);
+	protocol.setPrivateKey("test.key");
+	protocol.setCertificate("test.crt");
+	protocol.setMethod(net::ssl::Tlsv1);
+
+	Server server{std::move(protocol), net::address::Ip{"*", WITH_PORT}};
+#else
+	Server server{net::protocol::Tcp{}, net::address::Ip{"*", WITH_PORT}};
+#endif
+
+	server.setConnectionHandler([] (const std::shared_ptr<Connection> &client) {
+		std::cout << "server: new client connected" << std::endl;
+		client->send("Welcome to our server dude");
+	});
+	server.setReadHandler([] (const std::shared_ptr<Connection> &, const std::string &buffer) {
+		std::cout << "server: received: " << buffer << std::endl;
+	});
+	server.setWriteHandler([] (const std::shared_ptr<Connection> &, const std::string &buffer) {
+		std::cout << "server: sent: " << buffer << std::endl;
+	});
+	server.setDisconnectionHandler([] (const std::shared_ptr<Connection> &) {
+		std::cout << "server: client disconnected" << std::endl;
+	});
+
+	while (true) {
+		server.poll(-1);
+	}
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/test.crt	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICITCCAYoCCQCGm4grkVCohjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJG
+UjEPMA0GA1UECAwGRnJhbmNlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNTEwMjYyMDM0NThaFw0yNTEw
+MjMyMDM0NThaMFUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxITAfBgNV
+BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDp13OqVyOWyv5QWD4xr+Duw6SZ
+gU7D5huzsAOcneSI6JUhf+7Ecu6BQ2JGkFn4srIVkMWGQuImETJ8JCpSQH7rk+xO
+L9fTTK+TwhP2hW/Rf/b2gWedhJAS+gilqt4JNT7v2wFv+aTtRt/lpTXVSdtpLa/m
+Pdy219f6MAPgODJ/7QIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAJSnn/IBn1ZblfzP
+rJO/lE1Jwpmx3B7+oR/e4fkZd6JR3s06umGYWr2H+TPl/5dj9x0gPokhoIL9zCGq
+SxCPnOeaxjBkw7yh3Ks6m3xKxmK4aMpAtBHtwmbfQyIcgz71/lfCzbJ3WcKpn1ig
+IZbByt5QSSPcFORRzJJa35eHBdfX
+-----END CERTIFICATE-----
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/sockets/examples/test.key	Mon Dec 14 09:41:28 2015 +0100
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDp13OqVyOWyv5QWD4xr+Duw6SZgU7D5huzsAOcneSI6JUhf+7E
+cu6BQ2JGkFn4srIVkMWGQuImETJ8JCpSQH7rk+xOL9fTTK+TwhP2hW/Rf/b2gWed
+hJAS+gilqt4JNT7v2wFv+aTtRt/lpTXVSdtpLa/mPdy219f6MAPgODJ/7QIDAQAB
+AoGBANDt4ndQkgi56A1rOm50gVlzTg6lPPXFE/0xB5kYbcdxX0VmI7Q8KCMwTI9V
+jD2rk3e3OPSjr6FpfhzyxylkXMBz2BL5NRNPowCJbiMgZOUIzlcWPKo0tgf1bZJx
+YdB5U003ISGPPBjVOAjyizY7tJnaNvbpLQ0hbIAsvHPEAOnBAkEA9r3g8NQjPrvb
+oIr5SMIxM8HDJ1/q+MEBSFtRFzQpmur6P64Jsu96zCyencUYTxs0L/sottrj6dPC
+vjGCc6PjsQJBAPKdqK1knJv6Y95M2bnEwrymCFVdxCi7AxObStB+bg/+7mMCUqqX
+j2g71bfvhYakHV7CiaYrrORChwj6vTbimv0CQGpd2IZ5LOhyW2+N+YDgFg3Vzac/
+ti+eJEto8kAqgHUELvUctZmpmypBYe9pc91GQO0ePKL3IaE/ZIhRF4d6c0ECQH9A
+XiaD7PiKvjLs0A31u8ZCt4A+7BII9LYl73mntobBSbu4ji9Xyyn6qEAPa1ORZK49
+DwGPSuF2W2lESlYtSOkCQGrtczhx3IyJjk5e2Y1i/UddPKjviAysCSzcW6aVTNr9
+Y2L0sWmva2FKnkl9FDuEqxvmGr6OOkr5Ll7aWLzJri8=
+-----END RSA PRIVATE KEY-----