Commit 8e7897b7 authored by Felix Morgner's avatar Felix Morgner
Browse files

week10: add lecture examples

parent 1ce768ad
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>w10_01_AsioResolver</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <asio.hpp>
std::vector<std::string> resolve(std::string_view host) {
std::vector<std::string> addresses{};
asio::io_context context{};
asio::ip::tcp::resolver resolver{context};
auto endpoints = resolver.resolve(asio::ip::tcp::v4(), host.data(), "");
std::transform(std::begin(endpoints), std::end(endpoints), std::back_inserter(addresses), [](asio::ip::tcp::endpoint endpoint) {
return endpoint.address().to_string();
});
return addresses;
}
int main(int argc, char const * argv[]) {
std::string host{};
if (argc == 1) {
host = "www.hsr.ch";
} else {
host = argv[1];
}
auto addresses = resolve(host);
std::cout << "Addresses for: " << host << '\n';
std::copy(std::begin(addresses), std::end(addresses), std::ostream_iterator<std::string>{std::cout, "\n"});
}
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>w10_02_AsioGetRequest</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
#include <array>
#include <iostream>
#include <string>
#include <asio.hpp>
#include <sstream>
void getUrl(std::string_view domain) {
asio::io_context context{};
asio::ip::tcp::socket socket{context};
asio::ip::tcp::resolver resolver{context};
auto endpoints = resolver.resolve(domain, "80");
asio::connect(socket, endpoints);
std::ostringstream request{};
request << "GET / HTTP/1.1\r\n";
request << "Host: " << domain << "\r\n";
request << "\r\n";
asio::write(socket, asio::buffer(request.str()));
socket.shutdown(asio::ip::tcp::socket::shutdown_send);
do {
constexpr size_t bufferSize = 1024;
std::array<char, bufferSize> reply{};
asio::error_code errorCode{};
auto readLength = asio::read(socket, asio::buffer(reply.data(), bufferSize), errorCode);
if (errorCode == asio::error::eof) {
std::cout << "finished" << std::endl;
return;
} else if (errorCode) {
throw asio::system_error{errorCode};
}
std::cout << "Data received: ";
std::cout.write(reply.data(), readLength);
std::cout << std::endl;
} while (true);
socket.close();
}
int main(int argc, char const * argv[]) {
std::string host{};
if (argc == 1) {
host = "www.w3.org";
} else {
host = argv[1];
}
try {
getUrl(host);
} catch (asio::system_error const & e) {
std::cout << "An error occurred: " << e.what();
}
}
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>w10_03_AsioSyncEchoServer</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
#include <array>
#include <iostream>
#include <string>
#include <cstdlib>
#include <asio.hpp>
#include <sstream>
//
//void getUrl(std::string_view domain) {
// asio::io_context context{};
// asio::ip::tcp::socket socket{context};
// asio::ip::tcp::resolver resolver{context};
// auto endpoints = resolver.resolve(domain, "80");
// asio::connect(socket, endpoints);
//
// std::ostringstream request{};
// request << "GET / HTTP/1.1\r\n";
// request << "Host: " << domain << "\r\n";
// request << "\r\n";
// asio::write(socket, asio::buffer(request.str()));
// socket.shutdown(asio::ip::tcp::socket::shutdown_send);
//
// constexpr size_t bufferSize = 1024;
// std::array<char, bufferSize> reply{};
// asio::error_code errorCode{};
// do {
// auto readLength = asio::read(socket, asio::buffer(reply.data(), bufferSize), errorCode);
// if (errorCode == asio::error::eof) {
// std::cout << "finished" << std::endl;
// return;
// } else if (errorCode) {
// throw asio::system_error{errorCode};
// }
// std::cout << "Data received: ";
// std::cout.write(reply.data(), readLength);
// std::cout << std::endl;
// } while (true);
//}
void runEchoServer(unsigned short port) {
asio::io_context context{};
asio::ip::tcp::endpoint localEndpoint{asio::ip::tcp::v4(), port};
asio::ip::tcp::acceptor acceptor{context, localEndpoint};
acceptor.set_option(asio::ip::tcp::socket::reuse_address{});
std::cout << "accepting connections on: " << localEndpoint << std::endl;
asio::ip::tcp::endpoint peerEndpoint{};
asio::ip::tcp::socket peerSocket = acceptor.accept(peerEndpoint);
std::cout << "connection established with: " << peerEndpoint << std::endl;
do {
std::string message{};
asio::error_code errorCode{};
auto readLength = asio::read_until(peerSocket, asio::dynamic_buffer(message), '\n', errorCode);
if (errorCode == asio::error::eof) {
peerSocket.shutdown(asio::ip::tcp::socket::shutdown_both);
std::cout << "finished" << std::endl;
return;
} else if (errorCode) {
throw asio::system_error{errorCode};
}
std::cout << "Data received " << readLength << " byte: ";
std::cout << message;
std::cout << std::endl;
asio::write(peerSocket, asio::buffer(message.c_str(), readLength));
std::cout << "Reply sent" << std::endl;
} while (true);
}
int main(int argc, char const * argv[]) {
unsigned short port;
if (argc > 1) {
port = std::stoul(argv[1], nullptr, 10);
} else {
port = 1234;
}
try {
runEchoServer(port);
} catch (asio::system_error const & e) {
std::cout << "An error occurred: " << e.what();
}
}
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>w10_04_AsioFizzBuzzServer</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
#include "FizzBuzz.h"
#include <string>
std::string fizzbuzz(int number) {
using namespace std::string_literals;
std::string result { };
if (number % 3 == 0) {
result += "fizz"s;
}
if (number % 5 == 0) {
result += "buzz"s;
}
if (!result.empty()) {
return result;
}
return std::to_string(number);
}
#ifndef FIZZBUZZ_H_
#define FIZZBUZZ_H_
#include <string>
std::string fizzbuzz(int number);
#endif /* FIZZBUZZ_H_ */
#include "FizzBuzz.h"
#include "Server.h"
#include "Session.h"
#include <asio.hpp>
int main() {
asio::io_context context{};
Server server{context, 1234};
context.run();
}
#ifndef SERVER_H_
#define SERVER_H_
#include "Session.h"
#include <asio.hpp>
#include <memory>
#include <utility>
struct Server {
using tcp = asio::ip::tcp;
Server(asio::io_context & context, unsigned short port)
: acceptor{context, tcp::endpoint{tcp::v4(), port}} {
accept();
}
private:
void accept() {
auto acceptHandler = [this] (asio::error_code ec, tcp::socket peer) {
if (!ec) {
auto session = std::make_shared<Session>(std::move(peer));
session->start();
}
accept();
};
acceptor.async_accept(acceptHandler);
}
tcp::acceptor acceptor;
};
#endif /* SERVER_H_ */
#ifndef SESSION_H_
#define SESSION_H_
#include "FizzBuzz.h"
#include <asio.hpp>
#include <cstddef>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
struct Session : std::enable_shared_from_this<Session> {
explicit Session(asio::ip::tcp::socket socket) : socket{std::move(socket)} {
std::cout << "Starting Session for Client " << this->socket.remote_endpoint().address() << ':' << this->socket.remote_endpoint().port() << std::endl;
}
void start() {
read();
}
private:
void read() {
auto readCompletionHandler = [self = shared_from_this()] (asio::error_code ec, std::size_t length) {
if (ec) {
std::cout << "Closing session " << ec.message() << std::endl;
self->socket.close();
return;
}
int number{};
if (self->input >> number) {
self->input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
self->write(self->createReply(number));
}
};
asio::async_read_until(socket, buffer, '\n', readCompletionHandler);
}
void write(std::string input) {
auto data = std::make_shared<std::string>(input);
auto writeCompletionHandler = [self = shared_from_this(), data] (asio::error_code ec, std::size_t length){
if (ec) {
std::cout << "Closing session " << ec.message() << std::endl;
self->socket.close();
return;
}
self->read();
};
asio::async_write(socket, asio::buffer(data->c_str(), data->size()), writeCompletionHandler);
}
std::string createReply(int number) {
using namespace std::string_literals;
std::ostringstream reply{};
reply << number << ": "s << fizzbuzz(number) << '\n';
return reply.str();
}
asio::streambuf buffer{};
std::istream input{&buffer};
asio::ip::tcp::socket socket;
};
#endif /* SESSION_H_ */
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment