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.
352 lines
10 KiB
C++
352 lines
10 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_1_
|
|
#define DLIB_SOCKETS_KERNEl_1_
|
|
|
|
#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 "sockets_kernel_abstract.h"
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "../algs.h"
|
|
#include "../threads.h"
|
|
#include "../uintn.h"
|
|
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
// forward declarations
|
|
class socket_factory;
|
|
class listener;
|
|
class SOCKET_container;
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
// 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
|
|
);
|
|
|
|
unsigned short get_local_port (
|
|
) const { return connection_local_port; }
|
|
|
|
unsigned short 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 (
|
|
);
|
|
|
|
int shutdown (
|
|
);
|
|
|
|
// I would use SOCKET here but I don't want to include the windows
|
|
// header files since they bring in a bunch of unpleasantness. So
|
|
// I'm doing this instead which should ultimately be the same type
|
|
// as the SOCKET win the windows API.
|
|
typedef unsigned_type<void*>::type socket_descriptor_type;
|
|
|
|
int disable_nagle(
|
|
);
|
|
|
|
socket_descriptor_type get_socket_descriptor (
|
|
) const;
|
|
|
|
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
|
|
SOCKET_container& connection_socket;
|
|
const unsigned short connection_foreign_port;
|
|
const std::string connection_foreign_ip;
|
|
const unsigned short 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(
|
|
SOCKET_container sock,
|
|
unsigned short foreign_port,
|
|
const std::string& foreign_ip,
|
|
unsigned short local_port,
|
|
const std::string& local_ip
|
|
);
|
|
/*!
|
|
requires
|
|
sock is a socket handle and
|
|
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&); // copy constructor
|
|
connection& operator=(connection&); // assignment operator
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// 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
|
|
);
|
|
|
|
unsigned short get_listening_port (
|
|
) { return listening_port; }
|
|
|
|
const std::string& get_listening_ip (
|
|
) { return listening_ip; }
|
|
|
|
private:
|
|
|
|
// data members
|
|
SOCKET_container& listening_socket;
|
|
const unsigned short listening_port;
|
|
const std::string listening_ip;
|
|
const bool inaddr_any;
|
|
|
|
listener(
|
|
SOCKET_container sock,
|
|
unsigned short port,
|
|
const std::string& ip
|
|
);
|
|
/*!
|
|
requires
|
|
sock is a socket handle and
|
|
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&); // copy constructor
|
|
listener& operator=(listener&); // assignment operator
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
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_1.cpp"
|
|
#endif
|
|
|
|
#endif // DLIB_SOCKETS_KERNEl_1_
|
|
|