Using Sockets with C++

U

Linux sockets are always a useful tool for an application. In the simplest terms, a socket is a pseudo-file that represents a network connection. Once a socket has been created (using the proper primitives, and the proper parameters to identify the other host), writes to the socket are turned into network packets that get sent out, and data received from the network can be read from the socket.

In one regard, sockets are very similar to pipes: they look just like files to the programs using them, but do not result in read or writes to a disk; rather, they allow communicating with another program (local in the case of pipes, and possibly remote in the case of sockets). They also offer, as you mention, bidirectional communication (much like a pair of properly connected pipes could).

Finally, it is common for programs on a single machine to communicate using standard network protocols, such as TCP; it would be wasteful to go all the way to the network hardware (if any!), computing checksums, etc., just to go back to the same host: that’s where Unix domains sockets come in. Those are much like regular sockets, except they connect processes on the same host rather than remote processes, and do not attempt to use any network resources at all. In this way, they are a medium of inter-process communication.

As tripleee mentioned, in the course of the history of BSD, pipes were introduced earlier than sockets, and were reimplemented using sockets once those existed. The same reference, The Design and Implementation of the FreeBSD Operating System, mentions that pipes were then reverted to a non-socket implementation for performance reasons: this certainly underlines the fact that pipes share similarities.

Header File: Socket.h
#pragma once

#include <memory>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>

#ifndef TCP_USER_TIMEOUT
#define TCP_USER_TIMEOUT 18 
#endif

#define DEFAULT_TEST_PORT       1101
#define DEFAULT_TIMEOUT         1000

typedef struct Parameters
{
	int clientSocket; sockaddr_in clientAddr;
}
Parameters;

class Socket 
{
private:
	int m_sock = -1;
	int m_hostPort = -1;
		
public:
	Socket();
	Socket(int hostPort);
	~Socket();
	bool bind(void);
	bool isOpen(void);
	void disconnect();
	bool listen(void);	
	int currSocket(void);
	Parameters* accept(void);  
	bool connect(std::string host_name); 	
};
Source File: Socket.c
#include "Socket.h"

Socket::Socket()
{
	
}

Socket::Socket(int hostPort)
{
	m_hostPort = hostPort;
	m_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (m_sock == -1) 
	{
		disconnect();
		return;
	}
	bool option = 1;
}

Socket::~Socket() 
{
	disconnect();
}

bool Socket::isOpen(void) 
{
	return m_sock != -1;
}

int Socket::currSocket(void) 
{
	return m_sock;
}

bool Socket::bind(void) 
{
	if (isOpen() == false)	
		return false;
	struct sockaddr_in my_addr;
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(m_hostPort);
	memset(&(my_addr.sin_zero), 0, 8);
	my_addr.sin_addr.s_addr = INADDR_ANY;
	if (::bind(m_sock, (sockaddr*)&my_addr, sizeof(my_addr)) == -1)
		return false;
	return true;
}

bool Socket::listen(void) 
{
	if (isOpen() == false)	return false;
	if (::listen(m_sock, 10) == -1) 
		return false;
	return true;
}

Parameters* Socket::accept(void)
{
	socklen_t addr_size = 0;
	addr_size = sizeof(sockaddr_in);
	sockaddr_in clientAddr;    
	int result =:: accept(m_sock, (sockaddr*)&clientAddr, &addr_size);
	Parameters * params = (Parameters*)malloc(sizeof(Parameters));
	params->clientSocket = result;
	params->clientAddr = clientAddr;
	return params;
}

void Socket::disconnect()
{
	if (m_sock == -1)return;
	close(m_sock);
	m_sock = -1;
}

bool Socket::connect(std::string host_name) 
{    
	struct sockaddr_in my_addr;
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(m_hostPort);
	memset(&(my_addr.sin_zero), 0, sizeof(my_addr.sin_zero));
	inet_pton(AF_INET, host_name.c_str(), &my_addr.sin_addr);
	if (::connect(currSocket(), (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1) 
		return false; 
	return true;
}
Disclaimer: The present content may not be used for training artificial intelligence or machine learning algorithms. All other uses, including search, entertainment, and commercial use, are permitted.

Categories

Tags