scclib
Stable Cloud Computing C++ Library
Files | Classes | Enumerations
Internet tcp and udp networking

Tcp/ip and udp/ip networking. More...

Collaboration diagram for Internet tcp and udp networking:

Files

file  inet.h
 Internet tcp and udp networking.
 
file  inet.cc
 Internet tcp and udp networking implementation
 
file  inet.cc
 Tests for Internet tcp and udp networking sockets.
 
file  inet_stream.cc
 Tests for Internet tcp and udp networking streams.
 
file  inetaddr.cc
 Tests for Internet tcp and udp networking addresses.
 

Classes

class  scc::net::InetAddr
 Ipv6 internet address. More...
 
class  scc::net::InetTcpSock
 Internet transmission control protocol (tcp) socket. More...
 
class  scc::net::InetUdpSock
 Internet user datagram protocol (udp) socket. More...
 

Enumerations

enum  scc::net::InetAddrFlag {
  scc::net::prot_mask = 0xf , scc::net::ipv4 = 0x1 , scc::net::ipv6 = 0x2 , scc::net::type_mask = 0xf0 ,
  scc::net::any = 0x10 , scc::net::loopback = 0x20 , scc::net::unicast = 0x40 , scc::net::multicast = 0x80 ,
  scc::net::scope_mask = 0xff00 , scc::net::if_local = 0x0100 , scc::net::link_local = 0x0200 , scc::net::realm_local = 0x0400 ,
  scc::net::admin_local = 0x0800 , scc::net::site_local = 0x1000 , scc::net::org_local = 0x2000 , scc::net::global = 0x4000 ,
  scc::net::mcast_flags_mask = 0xf0000 , scc::net::mcast_rendezvous = 0x10000 , scc::net::mcast_prefix = 0x20000 , scc::net::mcast_dynamic = 0x40000 ,
  scc::net::mcast_reserved_mask = 0xff00000 , scc::net::mcast_all_nodes = 0x0100000 , scc::net::mcast_all_routers = 0x0200000 , scc::net::unicast_special_mask = 0xf0000000 ,
  scc::net::unique_local_address = 0x10000000
}
 Internet address flags. More...
 

Detailed Description

Tcp/ip and udp/ip networking.

Test examples from scclib/net/unittest/inet.cc

Streaming tcp client/server, also showing non-blocking socket connect:

TEST(inet_example, client_server_stream_test)
{
Logger log;
log.add_cout();
log.id("tcp client");
// this test sets up a client and server & streams some data between them
addr.host("::1"); // localhost
addr.port(9999);
// listening event
scc::util::Event listening;
std::packaged_task<int(void)> serv_task([&addr, &listening]()
{
Logger log;
log.add_cout();
log.id("tcp server");
try
{
sock.reuse_addr(true);
sock.bind(addr);
log << "server listening" << endl;
sock.listen();
// can play around with timeouts and timing this way...
//log << "sleep for a second" << endl;
//std::this_thread::sleep_for(std::chrono::seconds(1));
log << "signalling client" << endl;
listening.write(1);
auto conn = sock.accept(from);
log << "connection from " << from << endl;
scc::util::IoStream stream(conn, conn);
int count = 0;
for (string got; std::getline(stream, got);) // loop until eof (socket closed)
{
log << "got " << got << endl;
count += got.size();
stream << got << endl;
}
return count;
}
catch (exception& ex)
{
log << ex.what() << endl;
listening.write(1);
return -1;
}
});
auto fut = serv_task.get_future();
std::thread serv(std::move(serv_task)); // start server thread
Poller pin;
pin.set(listening, Poller::input);
while (1)
{
pin.wait(std::chrono::milliseconds(700));
if (pin.event(listening))
{
break;
}
log << "waiting for listener" << endl;
}
listening.read();
// use a non-blocking approach to add a timeout to the connect
sock.non_blocking(true);
error_code ec;
sock.connect(addr, ec);
if (ec.value() != 0 && ec.value() != EINPROGRESS)
{
log << "Non blocking connect failed: " << ec.message() << endl;
ASSERT_EQ(ec.value(), 0);
}
log << "waiting for 200 ms seconds to connect" << endl;
Poller pout;
pout.set(sock, Poller::output);
pout.wait(std::chrono::milliseconds(200));
if (!pout.event(sock))
{
log << "connect attempt timed out" << endl;
ASSERT_EQ(pout.event(sock), 0);
}
sock.non_blocking(false);
sock.connect(addr); // connect will either throw immediately or connect
log << "connected, sending stuff" << endl;
string line1("first line");
string line2("second line");
scc::util::IoStream stream(sock, sock);
string got;
ASSERT_TRUE(stream << line1 << endl);
ASSERT_TRUE(getline(stream, got));
ASSERT_EQ(got, line1);
ASSERT_TRUE(stream << line2 << endl);
ASSERT_TRUE(getline(stream, got));
ASSERT_EQ(got, line2);
sock.close();
serv.join();
int res = fut.get();
log << "got result=" << res << endl;
ASSERT_EQ(res, line1.size()+line2.size());
}
Ipv6 internet address.
Definition: inet.h:120
unsigned port() const
Get the port.
Definition: inet.cc:159
virtual std::string host() const
Get host.
Definition: inet.cc:188
Internet transmission control protocol (tcp) socket.
Definition: inet.h:251
Signaling kernel event counter.
Definition: event.h:79
uint64_t read()
Read from (decrement) the event counter.
Definition: event.cc:82
void write(uint64_t)
Write to (increment) the event counter.
Definition: event.cc:94
Input/output stream wrapper for reader/writer.
Definition: iostream.h:157
TEST(inet_example, client_server_stream_test)
[Inet client server]
Definition: inet.cc:521

Multicast udp client/server:

Port and address reuse with a multithreaded server:

TEST(inet_example, tcp_multiserver)
{
Logger log;
log.add_cout();
log.id("tcp client");
// this test sets up a client and server & streams some data between them
addr.host("::1"); // localhost
addr.port(9999);
condition_variable cv;
mutex mx;
int listening = 0; // how many threads are listening?
Event shut;
auto serv_task = [&addr, &mx, &listening, &cv, &shut](int i)
{
Logger log;
log.add_cout();
log.id(string("tcp server ")+to_string(i));
try
{
sock.reuse_addr(true);
sock.reuse_port(true);
/*
Port and address reuse allows us to bind the same address to two distinct sockets and accept connections. This may
provide better performance than spawning a new thread from a single acceptor, or competing to accept from a single listening socket.
*/
sock.bind(addr);
log << "server listening" << endl;
sock.listen();
log << "telling the client I am listening" << endl;
{
lock_guard<mutex> lk(mx);
listening++;
cv.notify_one();
}
int count = 0;
for (;;)
{
Poller p;
p.set(sock, Poller::input);
p.set(shut, Poller::input);
p.wait();
if (p.event(shut))
{
return count;
}
InetAddr from;
auto conn = sock.accept(from);
log << "connection from " << from << endl;
IoStream stream(conn, conn);
for (string got; std::getline(stream, got);) // loop until eof (socket closed)
{
log << "got size " << got.size() << " : " << got << endl;
count += got.size();
stream << got << endl;
}
}
return count;
}
catch (exception& ex)
{
log << ex.what() << endl;
lock_guard<mutex> lk(mx); // just to make sure the client cannot block
listening++;
cv.notify_one();
return 0;
}
};
auto fut1 = async(serv_task, 1);
auto fut2 = async(serv_task, 2);
auto fut3 = async(serv_task, 3);
unique_lock<mutex> lk(mx);
cv.wait(lk, [&listening]
{
return listening == 3; // wait for all the threads to wake up
});
int count = 0;
for (int i = 0; i < 10; i++)
{
InetTcpSock sock;
sock.connect(addr);
log << "connected #" << i << ", sending stuff" << endl;
string line1("first line");
string line2("second line");
IoStream stream(sock, sock);
string got;
ASSERT_TRUE(stream << line1 << endl);
ASSERT_TRUE(getline(stream, got));
ASSERT_EQ(got, line1);
ASSERT_TRUE(stream << line2 << endl);
ASSERT_TRUE(getline(stream, got));
ASSERT_EQ(got, line2);
count += line1.size()+line2.size();
}
shut.write(1);
int res = fut1.get();
res += fut2.get();
res += fut3.get();
log << "got result=" << res << endl;
ASSERT_EQ(res, count);
}

Enumeration Type Documentation

◆ InetAddrFlag

Internet address flags.

Enumerator
prot_mask 

Protocol mask.

ipv4 

IPv4.

ipv6 

IPv6.

type_mask 

Address mask.

any 

Any address.

loopback 

Loopback address.

unicast 

Unicast address.

multicast 

Multicast address.

scope_mask 

Scope for multicast addresses mask.

if_local 

Traffic is restricted to the local interface.

link_local 

Traffic is restricted to the local link.

realm_local 

Traffic is restricted to the local realm.

admin_local 

Traffic is restricted to the local admin.

site_local 

Traffic is restricted to the local site.

org_local 

Traffic is restricted to the local organization.

global 

Global traffic is allowed.

mcast_flags_mask 

Multicast flags mask.

mcast_rendezvous 

Address has a rendezvous point embedded.

mcast_prefix 

Prefix-based address.

mcast_dynamic 

Dynamic (temporary) address, otherwise permanent (assigned).

mcast_reserved_mask 

Some reserved multicast addresses.

mcast_all_nodes 

Reaches all nodes in the scope, e.g. ff0X::1.

mcast_all_routers 

Reaches all routers in the scope, e.g. ff0X::2.

unicast_special_mask 

Some special unicast addresses.

unique_local_address 

Address which can be used freely within a site: e.g. fd00::/8.

Examples
net/unittest/inet.cc, net/unittest/inetaddr.cc, and net/unittest/net_if.cc.

Definition at line 73 of file inet.h.