Skip to content

akure/sockpp

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sockpp

Simple C++11 socket library.

This is a fairly low-level C++ wrapper around the Berkley sockets library using socket, acceptor, and connector classes that are familiar concepts from other languages.

Currently the library only supports IPv4, but soon UNIX socks will be supported, and eventually IPv6.

The base socket wraps a system integer socket handle, and maintains its lifetime. When the object goes out of scope, it closes the underlying socket handle. Socket objects are generally moveable but not copyable. A socket object can be transferred from one scope or thread to another using std::move().

All code in the library lives within the sockpp C++ namespace.

TCP Sockets

TCP applications are usually set up as either servers or clients. The tcp_acceptor is used to create a TCP server. It binds an address and listens on a known port to accept incoming connections. When a connection is accepted, a new, streaming tcp_socket is created. That new socket can be handled directly or moved to a thread (or thread pool) for processing.

Conversely, to create a TCP client, a tcp_connector object is created and connected to a server at a known address (host and socket). When connected, the socket is a streaming one which can be used to read and write, directly.

TCP server: tcp_acceptor

The tcp_acceptor is used to set up a server and listen for incoming connections.

int16_t port = 12345;
sockpp::tcp_acceptor acc(port);

if (!acc)
	report_error(strerror(acc.last_error()));

// Accept a new client connection
sockpp::tcp_socket sock = acc.accept();

The acceptor normally sits in a loop accepting new connections, and passes them off to another process, thread, or thread pool to interact with the client. In standard C++, this could look like:

while (true) {
	// Accept a new client connection
	sockpp::tcp_socket sock = acc.accept();

	if (!sock) {
		cerr << "Error accepting incoming connection: " 
			<< ::strerror(acc.last_error()) << endl;
	}
	else {
		// Create a thread and transfer the new stream to it.
		thread thr(run_echo, std::move(sock));
		thr.detach();
	}
}

The hazards of a thread-pre-connection design is well documented, but the same technique can be used to pass the socket into a thread pool, if one is available.

TCP Client: tcp_connector

The TCP client is somewhat simpler in that a tcp_connector object is created and connected, then can be used to read and write data directly.

sockpp::tcp_connector conn;
int16_t port = 12345;

if (!conn.connect(sockpp::inet_address("localhost", port)))
	report_error(strerror(acc.last_error()));

conn.write_n("Hello", 5);

char buf[5];
int n = conn.read(buf, 5);

About

Simple modern C++ socket library

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 92.8%
  • Makefile 6.4%
  • Shell 0.8%