You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
concurrentqueue/benchmarks/dlib/sockets/sockets_kernel_2.h

397 lines
11 KiB
C++

// Copyright (C) 2003 Davis E. King (davis@dlib.net), Miguel Grinberg
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SOCKETS_KERNEl_2_
#define DLIB_SOCKETS_KERNEl_2_
#ifdef DLIB_ISO_CPP_ONLY
#error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code. Turn DLIB_ISO_CPP_ONLY off if you want to use it."
#endif
#include "../platform.h"
#include "sockets_kernel_abstract.h"
#define _BSD_SOCKLEN_T_
#include <ctime>
#include <memory>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#ifndef HPUX
#include <sys/select.h>
#endif
#include <arpa/inet.h>
#include <signal.h>
#include <inttypes.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/param.h>
#include <netinet/in.h>
#include "../threads.h"
#include "../algs.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
// forward declarations
class socket_factory;
class listener;
// ----------------------------------------------------------------------------------------
// lookup functions
int
get_local_hostname (
std::string& hostname
);
// -----------------
int
hostname_to_ip (
const std::string& hostname,
std::string& ip,
int n = 0
);
// -----------------
int
ip_to_hostname (
const std::string& ip,
std::string& hostname
);
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// connection object
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class connection
{
/*!
INITIAL_VALUE
sd == false
sdo == false
sdr == 0
CONVENTION
connection_socket == the socket handle for this connection.
connection_foreign_port == the port that foreign host is using for
this connection
connection_foreign_ip == a string containing the IP address of the
foreign host
connection_local_port == the port that the local host is using for
this connection
connection_local_ip == a string containing the IP address of the
local interface being used by this connection
sd == if shutdown() has been called then true
else false
sdo == if shutdown_outgoing() has been called then true
else false
sdr == the return value of shutdown() if it has been
called. if it hasn't been called then 0
!*/
friend class listener; // make listener a friend of connection
// make create_connection a friend of connection
friend int create_connection (
connection*& new_connection,
unsigned short foreign_port,
const std::string& foreign_ip,
unsigned short local_port,
const std::string& local_ip
);
public:
~connection();
void* user_data;
long write (
const char* buf,
long num
);
long read (
char* buf,
long num
);
long read (
char* buf,
long num,
unsigned long timeout
);
int get_local_port (
) const { return connection_local_port; }
int get_foreign_port (
) const { return connection_foreign_port; }
const std::string& get_local_ip (
) const { return connection_local_ip; }
const std::string& get_foreign_ip (
) const { return connection_foreign_ip; }
int shutdown_outgoing (
)
{
sd_mutex.lock();
if (sdo || sd)
{
sd_mutex.unlock();
return sdr;
}
sdo = true;
sdr = ::shutdown(connection_socket,SHUT_WR);
int temp = sdr;
sd_mutex.unlock();
return temp;
}
int shutdown (
)
{
sd_mutex.lock();
if (sd)
{
sd_mutex.unlock();
return sdr;
}
sd = true;
sdr = ::shutdown(connection_socket,SHUT_RDWR);
int temp = sdr;
sd_mutex.unlock();
return temp;
}
int disable_nagle(
);
typedef int socket_descriptor_type;
socket_descriptor_type get_socket_descriptor (
) const { return connection_socket; }
private:
bool readable (
unsigned long timeout
) const;
/*!
requires
- timeout < 2000000
ensures
- returns true if a read call on this connection will not block.
- returns false if a read call on this connection will block or if
there was an error.
!*/
bool sd_called (
)const
/*!
ensures
- returns true if shutdown() has been called else
- returns false
!*/
{
sd_mutex.lock();
bool temp = sd;
sd_mutex.unlock();
return temp;
}
bool sdo_called (
)const
/*!
ensures
- returns true if shutdown_outgoing() or shutdown() has been called
else returns false
!*/
{
sd_mutex.lock();
bool temp = false;
if (sdo || sd)
temp = true;
sd_mutex.unlock();
return temp;
}
// data members
int connection_socket;
const int connection_foreign_port;
const std::string connection_foreign_ip;
const int connection_local_port;
const std::string connection_local_ip;
bool sd; // called shutdown
bool sdo; // called shutdown_outgoing
int sdr; // return value for shutdown
mutex sd_mutex; // a lock for the three above vars
connection(
int sock,
int foreign_port,
const std::string& foreign_ip,
int local_port,
const std::string& local_ip
);
/*!
requires
- sock is a socket handle
- sock is the handle for the connection between foreign_ip:foreign_port
and local_ip:local_port
ensures
- *this is initialized correctly with the above parameters
!*/
// restricted functions
connection();
connection(connection&); // copy constructor
connection& operator=(connection&); // assignement opertor
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// listener object
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class listener
{
/*!
CONVENTION
if (inaddr_any == false)
{
listening_ip == a string containing the address the listener is
listening on
}
else
{
the listener is listening on all interfaces
}
listening_port == the port the listener is listening on
listening_socket == the listening socket handle for this object
!*/
// make the create_listener a friend of listener
friend int create_listener (
listener*& new_listener,
unsigned short port,
const std::string& ip
);
public:
~listener();
int accept (
connection*& new_connection,
unsigned long timeout = 0
);
int accept (
std::unique_ptr<connection>& new_connection,
unsigned long timeout = 0
);
int get_listening_port (
) const { return listening_port; }
const std::string& get_listening_ip (
) const { return listening_ip; }
private:
// data members
int listening_socket;
const int listening_port;
const std::string listening_ip;
const bool inaddr_any;
listener(
int sock,
int port,
const std::string& ip
);
/*!
requires
- sock is a socket handle
- sock is listening on the port and ip(may be "") indicated in the above
parameters
ensures
- *this is initialized correctly with the above parameters
!*/
// restricted functions
listener();
listener(listener&); // copy constructor
listener& operator=(listener&); // assignement opertor
};
// ----------------------------------------------------------------------------------------
int create_listener (
listener*& new_listener,
unsigned short port,
const std::string& ip = ""
);
int create_connection (
connection*& new_connection,
unsigned short foreign_port,
const std::string& foreign_ip,
unsigned short local_port = 0,
const std::string& local_ip = ""
);
int create_listener (
std::unique_ptr<listener>& new_listener,
unsigned short port,
const std::string& ip = ""
);
int create_connection (
std::unique_ptr<connection>& new_connection,
unsigned short foreign_port,
const std::string& foreign_ip,
unsigned short local_port = 0,
const std::string& local_ip = ""
);
// ----------------------------------------------------------------------------------------
}
#ifdef NO_MAKEFILE
#include "sockets_kernel_2.cpp"
#endif
#endif // DLIB_SOCKETS_KERNEl_2_