mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-05-17 04:37:50 +00:00
Master commit of OpenFace.
This commit is contained in:
6
lib/3rdParty/dlib/include/dlib/sockets/posix.h
vendored
Normal file
6
lib/3rdParty/dlib/include/dlib/sockets/posix.h
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SOCKETS_KERNEl_1_
|
||||
#include "sockets_kernel_2.h"
|
||||
#endif
|
||||
|
||||
341
lib/3rdParty/dlib/include/dlib/sockets/sockets_extensions.cpp
vendored
Normal file
341
lib/3rdParty/dlib/include/dlib/sockets/sockets_extensions.cpp
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SOCKETS_EXTENSIONs_CPP
|
||||
#define DLIB_SOCKETS_EXTENSIONs_CPP
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "../sockets.h"
|
||||
#include "../error.h"
|
||||
#include "sockets_extensions.h"
|
||||
#include "../timer.h"
|
||||
#include "../algs.h"
|
||||
#include "../timeout.h"
|
||||
#include "../misc_api.h"
|
||||
#include "../serialize.h"
|
||||
#include "../string.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
network_address::
|
||||
network_address(
|
||||
const std::string& full_address
|
||||
)
|
||||
{
|
||||
std::istringstream sin(full_address);
|
||||
sin >> *this;
|
||||
if (!sin || sin.peek() != EOF)
|
||||
throw invalid_network_address("invalid network address: " + full_address);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void serialize(
|
||||
const network_address& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
serialize(item.host_address, out);
|
||||
serialize(item.port, out);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void deserialize(
|
||||
network_address& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
deserialize(item.host_address, in);
|
||||
deserialize(item.port, in);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
std::ostream& operator<< (
|
||||
std::ostream& out,
|
||||
const network_address& item
|
||||
)
|
||||
{
|
||||
out << item.host_address << ":" << item.port;
|
||||
return out;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
std::istream& operator>> (
|
||||
std::istream& in,
|
||||
network_address& item
|
||||
)
|
||||
{
|
||||
std::string temp;
|
||||
in >> temp;
|
||||
|
||||
std::string::size_type pos = temp.find_last_of(":");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
in.setstate(std::ios::badbit);
|
||||
return in;
|
||||
}
|
||||
|
||||
item.host_address = temp.substr(0, pos);
|
||||
try
|
||||
{
|
||||
item.port = sa = temp.substr(pos+1);
|
||||
} catch (std::exception& )
|
||||
{
|
||||
in.setstate(std::ios::badbit);
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const std::string& host_or_ip,
|
||||
unsigned short port
|
||||
)
|
||||
{
|
||||
std::string ip;
|
||||
connection* con;
|
||||
if (is_ip_address(host_or_ip))
|
||||
{
|
||||
ip = host_or_ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hostname_to_ip(host_or_ip,ip))
|
||||
throw socket_error(ERESOLVE,"unable to resolve '" + host_or_ip + "' in connect()");
|
||||
}
|
||||
|
||||
if(create_connection(con,port,ip))
|
||||
{
|
||||
std::ostringstream sout;
|
||||
sout << "unable to connect to '" << host_or_ip << ":" << port << "'";
|
||||
throw socket_error(sout.str());
|
||||
}
|
||||
|
||||
return con;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const network_address& addr
|
||||
)
|
||||
{
|
||||
return connect(addr.host_address, addr.port);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace connect_timeout_helpers
|
||||
{
|
||||
mutex connect_mutex;
|
||||
signaler connect_signaler(connect_mutex);
|
||||
timestamper ts;
|
||||
long outstanding_connects = 0;
|
||||
|
||||
struct thread_data
|
||||
{
|
||||
std::string host_or_ip;
|
||||
unsigned short port;
|
||||
connection* con;
|
||||
bool connect_ended;
|
||||
bool error_occurred;
|
||||
};
|
||||
|
||||
void thread(void* param)
|
||||
{
|
||||
thread_data p = *static_cast<thread_data*>(param);
|
||||
try
|
||||
{
|
||||
p.con = connect(p.host_or_ip, p.port);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
p.error_occurred = true;
|
||||
}
|
||||
|
||||
auto_mutex M(connect_mutex);
|
||||
// report the results back to the connect() call that spawned this
|
||||
// thread.
|
||||
static_cast<thread_data*>(param)->con = p.con;
|
||||
static_cast<thread_data*>(param)->error_occurred = p.error_occurred;
|
||||
connect_signaler.broadcast();
|
||||
|
||||
// wait for the call to connect() that spawned this thread to terminate
|
||||
// before we delete the thread_data struct.
|
||||
while (static_cast<thread_data*>(param)->connect_ended == false)
|
||||
connect_signaler.wait();
|
||||
|
||||
connect_signaler.broadcast();
|
||||
--outstanding_connects;
|
||||
delete static_cast<thread_data*>(param);
|
||||
}
|
||||
}
|
||||
|
||||
connection* connect (
|
||||
const std::string& host_or_ip,
|
||||
unsigned short port,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
using namespace connect_timeout_helpers;
|
||||
|
||||
auto_mutex M(connect_mutex);
|
||||
|
||||
const uint64 end_time = ts.get_timestamp() + timeout*1000;
|
||||
|
||||
|
||||
// wait until there are less than 100 outstanding connections
|
||||
while (outstanding_connects > 100)
|
||||
{
|
||||
uint64 cur_time = ts.get_timestamp();
|
||||
if (end_time > cur_time)
|
||||
{
|
||||
timeout = static_cast<unsigned long>((end_time - cur_time)/1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw socket_error("unable to connect to '" + host_or_ip + "' because connect timed out");
|
||||
}
|
||||
|
||||
connect_signaler.wait_or_timeout(timeout);
|
||||
}
|
||||
|
||||
|
||||
thread_data* data = new thread_data;
|
||||
data->host_or_ip = host_or_ip.c_str();
|
||||
data->port = port;
|
||||
data->con = 0;
|
||||
data->connect_ended = false;
|
||||
data->error_occurred = false;
|
||||
|
||||
|
||||
if (create_new_thread(thread, data) == false)
|
||||
{
|
||||
delete data;
|
||||
throw socket_error("unable to connect to '" + host_or_ip);
|
||||
}
|
||||
|
||||
++outstanding_connects;
|
||||
|
||||
// wait until we have a connection object
|
||||
while (data->con == 0)
|
||||
{
|
||||
uint64 cur_time = ts.get_timestamp();
|
||||
if (end_time > cur_time && data->error_occurred == false)
|
||||
{
|
||||
timeout = static_cast<unsigned long>((end_time - cur_time)/1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// let the thread know that it should terminate
|
||||
data->connect_ended = true;
|
||||
connect_signaler.broadcast();
|
||||
if (data->error_occurred)
|
||||
throw socket_error("unable to connect to '" + host_or_ip);
|
||||
else
|
||||
throw socket_error("unable to connect to '" + host_or_ip + "' because connect timed out");
|
||||
}
|
||||
|
||||
connect_signaler.wait_or_timeout(timeout);
|
||||
}
|
||||
|
||||
// let the thread know that it should terminate
|
||||
data->connect_ended = true;
|
||||
connect_signaler.broadcast();
|
||||
return data->con;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
bool is_ip_address (
|
||||
std::string ip
|
||||
)
|
||||
{
|
||||
for (std::string::size_type i = 0; i < ip.size(); ++i)
|
||||
{
|
||||
if (ip[i] == '.')
|
||||
ip[i] = ' ';
|
||||
}
|
||||
std::istringstream sin(ip);
|
||||
|
||||
bool bad = false;
|
||||
int num;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
sin >> num;
|
||||
if (!sin || num < 0 || num > 255)
|
||||
{
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sin.get() != EOF)
|
||||
bad = true;
|
||||
|
||||
return !bad;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void close_gracefully (
|
||||
connection* con,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
scoped_ptr<connection> ptr(con);
|
||||
close_gracefully(ptr,timeout);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void close_gracefully (
|
||||
scoped_ptr<connection>& con,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
if (!con)
|
||||
return;
|
||||
|
||||
if(con->shutdown_outgoing())
|
||||
{
|
||||
// there was an error so just close it now and return
|
||||
con.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dlib::timeout t(*con,&connection::shutdown,timeout);
|
||||
|
||||
char junk[100];
|
||||
// wait for the other end to close their side
|
||||
while (con->read(junk,sizeof(junk)) > 0) ;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
con.reset();
|
||||
throw;
|
||||
}
|
||||
|
||||
con.reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SOCKETS_EXTENSIONs_CPP
|
||||
|
||||
|
||||
148
lib/3rdParty/dlib/include/dlib/sockets/sockets_extensions.h
vendored
Normal file
148
lib/3rdParty/dlib/include/dlib/sockets/sockets_extensions.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SOCKETS_EXTENSIONs_
|
||||
#define DLIB_SOCKETS_EXTENSIONs_
|
||||
|
||||
#include <string>
|
||||
#include "../sockets.h"
|
||||
#include "sockets_extensions_abstract.h"
|
||||
#include "../smart_pointers.h"
|
||||
#include <iosfwd>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class invalid_network_address : public dlib::error
|
||||
{
|
||||
public:
|
||||
invalid_network_address(const std::string& msg) : dlib::error(msg) {};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct network_address
|
||||
{
|
||||
network_address() : port(0){}
|
||||
|
||||
network_address(
|
||||
const std::string& full_address
|
||||
);
|
||||
|
||||
network_address (
|
||||
const char* full_address
|
||||
)
|
||||
{
|
||||
*this = network_address(std::string(full_address));
|
||||
}
|
||||
|
||||
network_address(
|
||||
const std::string& host_address_,
|
||||
const unsigned short port_
|
||||
) : host_address(host_address_), port(port_) {}
|
||||
|
||||
std::string host_address;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
inline bool operator < (
|
||||
const network_address& a,
|
||||
const network_address& b
|
||||
)
|
||||
{
|
||||
if (a.host_address < b.host_address)
|
||||
return true;
|
||||
else if (a.host_address > b.host_address)
|
||||
return false;
|
||||
else if (a.port < b.port)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator== (
|
||||
const network_address& a,
|
||||
const network_address& b
|
||||
) { return a.host_address == b.host_address && a.port == b.port; }
|
||||
|
||||
inline bool operator != (
|
||||
const network_address& a,
|
||||
const network_address& b
|
||||
) { return !(a == b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void serialize(
|
||||
const network_address& item,
|
||||
std::ostream& out
|
||||
);
|
||||
|
||||
void deserialize(
|
||||
network_address& item,
|
||||
std::istream& in
|
||||
);
|
||||
|
||||
std::ostream& operator<< (
|
||||
std::ostream& out,
|
||||
const network_address& item
|
||||
);
|
||||
|
||||
std::istream& operator>> (
|
||||
std::istream& in,
|
||||
network_address& item
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const std::string& host_or_ip,
|
||||
unsigned short port
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const network_address& addr
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const std::string& host_or_ip,
|
||||
unsigned short port,
|
||||
unsigned long timeout
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
bool is_ip_address (
|
||||
std::string ip
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void close_gracefully (
|
||||
connection* con,
|
||||
unsigned long timeout = 500
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void close_gracefully (
|
||||
scoped_ptr<connection>& con,
|
||||
unsigned long timeout = 500
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "sockets_extensions.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_SOCKETS_EXTENSIONs_
|
||||
|
||||
299
lib/3rdParty/dlib/include/dlib/sockets/sockets_extensions_abstract.h
vendored
Normal file
299
lib/3rdParty/dlib/include/dlib/sockets/sockets_extensions_abstract.h
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SOCKETS_EXTENSIONs_ABSTRACT_
|
||||
#ifdef DLIB_SOCKETS_EXTENSIONs_ABSTRACT_
|
||||
|
||||
#include <string>
|
||||
#include "sockets_kernel_abstract.h"
|
||||
#include "../smart_pointers.h"
|
||||
#include "../error.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class invalid_network_address : public dlib::error
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is the exception thrown by network_address's constructor if the
|
||||
input is invalid.
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct network_address
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is simply a container for two things:
|
||||
- A host machine address which is either an IP address or DNS name
|
||||
for a machine.
|
||||
- A port number.
|
||||
|
||||
Together, these things define a machine and port on that machine.
|
||||
!*/
|
||||
|
||||
network_address(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- host_address == ""
|
||||
- #port == 0
|
||||
!*/
|
||||
|
||||
network_address(
|
||||
const std::string& full_address
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- interprets full_address as a network address of the form:
|
||||
host_address:port
|
||||
and assigns each part into #host_address and #port. For example,
|
||||
network_address("localhost:80") would result in a network_address
|
||||
object where host_address was "localhost" and port was 80.
|
||||
throws
|
||||
- invalid_network_address
|
||||
This exception is thrown if the full_address string can't be
|
||||
interpreted as a valid network address.
|
||||
!*/
|
||||
|
||||
network_address (
|
||||
const char* full_address
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- full_address == a valid pointer to a null terminated string
|
||||
ensures
|
||||
- Invoking this constructor is equivalent to performing
|
||||
network_address(std::string(full_address))
|
||||
!*/
|
||||
|
||||
network_address(
|
||||
const std::string& host_address_,
|
||||
const unsigned short port_
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #host_address == host_address_
|
||||
- #port == port_
|
||||
!*/
|
||||
|
||||
|
||||
std::string host_address;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
inline bool operator < (
|
||||
const network_address& a,
|
||||
const network_address& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- provides a total ordering over network_address objects so you can use them in
|
||||
the standard associative containers. The ordering is defined such that if
|
||||
you sorted network addresses they would sort first on the host_address string
|
||||
and then, for network_address objects with equal host_address, they would
|
||||
sort on the port number
|
||||
!*/
|
||||
|
||||
inline bool operator== (
|
||||
const network_address& a,
|
||||
const network_address& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns true if a and b contain exactly the same address and false otherwise.
|
||||
That is, the following must be true for this function to return true:
|
||||
- a.host_address == b.host_address
|
||||
- a.port == b.port
|
||||
Note that this means that two addresses which are logically equivalent but
|
||||
written differently will not compare equal. For example, suppose example.com
|
||||
has the IP address 10.1.1.1. Then network_address("10.1.1.1:80") and
|
||||
network_address("example.com:80") really refer to the same network resource
|
||||
but will nevertheless not compare equal since.
|
||||
!*/
|
||||
|
||||
inline bool operator != (
|
||||
const network_address& a,
|
||||
const network_address& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns !(a == b)
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void serialize(
|
||||
const network_address& item,
|
||||
std::ostream& out
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- provides serialization support
|
||||
!*/
|
||||
|
||||
void deserialize(
|
||||
network_address& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- provides deserialization support
|
||||
!*/
|
||||
|
||||
std::ostream& operator<< (
|
||||
std::ostream& out,
|
||||
const network_address& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- writes the given network_address to the output stream. The format is the
|
||||
host_address, then a colon, then the port number. So for example:
|
||||
cout << network_address("localhost", 80);
|
||||
would print:
|
||||
localhost:80
|
||||
- returns #out
|
||||
!*/
|
||||
|
||||
std::istream& operator>> (
|
||||
std::istream& in,
|
||||
network_address& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- reads a network_address from the given input stream. The expected format is
|
||||
the same as the one used to print them by the above operator<<() routine.
|
||||
- returns #in
|
||||
- if (there is an error reading the network_address) then
|
||||
- #in.good() == false
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const std::string& host_or_ip,
|
||||
unsigned short port
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns a connection object that is connected to the given host at the
|
||||
given port
|
||||
throws
|
||||
- dlib::socket_error
|
||||
This exception is thrown if there is some problem that prevents us from
|
||||
creating the connection
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const network_address& addr
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns connect(addr.host_address, addr_port);
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection* connect (
|
||||
const std::string& host_or_ip,
|
||||
unsigned short port,
|
||||
unsigned long timeout
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns a connection object that is connected to the given host at the
|
||||
given port.
|
||||
- blocks for at most timeout milliseconds
|
||||
throws
|
||||
- dlib::socket_error
|
||||
This exception is thrown if there is some problem that prevents us from
|
||||
creating the connection or if timeout milliseconds elapses before the
|
||||
connect is successful.
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool is_ip_address (
|
||||
std::string ip
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (ip is a valid ip address) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void close_gracefully (
|
||||
connection* con,
|
||||
unsigned long timeout = 500
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- con == a valid pointer to a connection object or 0
|
||||
ensures
|
||||
- This function does nothing if con == 0, otherwise it performs the following:
|
||||
- performs a graceful close of the given connection and if it takes longer
|
||||
than timeout milliseconds to complete then forces the connection closed.
|
||||
- Specifically, a graceful close means that the outgoing part of con is
|
||||
closed (a FIN is sent) and then we wait for the other end to to close
|
||||
their end of the connection. This way any data still on its way to
|
||||
the other end of the connection will be received properly.
|
||||
- This function will block until the graceful close is completed or we
|
||||
timeout.
|
||||
- calls "delete con;". Thus con is no longer a valid pointer after this
|
||||
function has finished.
|
||||
throws
|
||||
- std::bad_alloc or dlib::thread_error
|
||||
If either of these exceptions are thrown con will still be closed via
|
||||
"delete con;"
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void close_gracefully (
|
||||
scoped_ptr<connection>& con,
|
||||
unsigned long timeout = 500
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- con == a valid pointer to a connection object or con.get() == 0
|
||||
ensures
|
||||
- This function does nothing if con.get() == 0, otherwise it performs the
|
||||
following:
|
||||
- performs a graceful close of the given connection and if it takes longer
|
||||
than timeout milliseconds to complete then forces the connection closed.
|
||||
- Specifically, a graceful close means that the outgoing part of con is
|
||||
closed (a FIN is sent) and then we wait for the other end to to close
|
||||
their end of the connection. This way any data still on its way to
|
||||
the other end of the connection will be received properly.
|
||||
- This function will block until the graceful close is completed or we
|
||||
timeout.
|
||||
- #con.get() == 0. Thus con is no longer a valid pointer after this
|
||||
function has finished.
|
||||
throws
|
||||
- std::bad_alloc or dlib::thread_error
|
||||
If either of these exceptions are thrown con will still be closed and
|
||||
deleted (i.e. #con.get() == 0).
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SOCKETS_EXTENSIONs_ABSTRACT_
|
||||
|
||||
|
||||
978
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_1.cpp
vendored
Normal file
978
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_1.cpp
vendored
Normal file
@@ -0,0 +1,978 @@
|
||||
// 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_CPp_
|
||||
#define DLIB_SOCKETS_KERNEL_1_CPp_
|
||||
#include "../platform.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#ifndef _WINSOCKAPI_
|
||||
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
|
||||
#endif
|
||||
|
||||
#include "../windows_magic.h"
|
||||
|
||||
#include "sockets_kernel_1.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
|
||||
// tell visual studio to link to the libraries we need if we are
|
||||
// in fact using visual studio
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment (lib, "ws2_32.lib")
|
||||
#endif
|
||||
|
||||
#include "../assert.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class SOCKET_container
|
||||
{
|
||||
/*!
|
||||
This object is just a wrapper around the SOCKET type. It exists
|
||||
so that we can #include the windows.h and Winsock2.h header files
|
||||
in this cpp file and not at all in the header file.
|
||||
!*/
|
||||
public:
|
||||
SOCKET_container (
|
||||
SOCKET s = INVALID_SOCKET
|
||||
) : val(s) {}
|
||||
|
||||
SOCKET val;
|
||||
operator SOCKET&() { return val; }
|
||||
|
||||
SOCKET_container& operator= (
|
||||
const SOCKET& s
|
||||
) { val = s; return *this; }
|
||||
|
||||
bool operator== (
|
||||
const SOCKET& s
|
||||
) const { return s == val; }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// stuff to ensure that WSAStartup() is always called before any sockets stuff is needed
|
||||
|
||||
namespace sockets_kernel_1_mutex
|
||||
{
|
||||
mutex startup_lock;
|
||||
}
|
||||
|
||||
class sockets_startupdown
|
||||
{
|
||||
public:
|
||||
sockets_startupdown();
|
||||
~sockets_startupdown() { WSACleanup( ); }
|
||||
|
||||
};
|
||||
sockets_startupdown::sockets_startupdown (
|
||||
)
|
||||
{
|
||||
WSADATA wsaData;
|
||||
WSAStartup (MAKEWORD(2,0), &wsaData);
|
||||
}
|
||||
|
||||
void sockets_startup()
|
||||
{
|
||||
// mutex crap to make this function thread-safe
|
||||
sockets_kernel_1_mutex::startup_lock.lock();
|
||||
static sockets_startupdown a;
|
||||
sockets_kernel_1_mutex::startup_lock.unlock();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// lookup functions
|
||||
|
||||
int
|
||||
get_local_hostname (
|
||||
std::string& hostname
|
||||
)
|
||||
{
|
||||
// ensure that WSAStartup has been called and WSACleanup will eventually
|
||||
// be called when program ends
|
||||
sockets_startup();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
char temp[NI_MAXHOST];
|
||||
if (gethostname(temp,NI_MAXHOST) == SOCKET_ERROR )
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
hostname = temp;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -----------------
|
||||
|
||||
int
|
||||
hostname_to_ip (
|
||||
const std::string& hostname,
|
||||
std::string& ip,
|
||||
int n
|
||||
)
|
||||
{
|
||||
// ensure that WSAStartup has been called and WSACleanup will eventually
|
||||
// be called when program ends
|
||||
sockets_startup();
|
||||
|
||||
try
|
||||
{
|
||||
// lock this mutex since gethostbyname isn't really thread safe
|
||||
auto_mutex M(sockets_kernel_1_mutex::startup_lock);
|
||||
|
||||
// if no hostname was given then return error
|
||||
if ( hostname.empty())
|
||||
return OTHER_ERROR;
|
||||
|
||||
hostent* address;
|
||||
address = gethostbyname(hostname.c_str());
|
||||
|
||||
if (address == 0)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
// find the nth address
|
||||
in_addr* addr = reinterpret_cast<in_addr*>(address->h_addr_list[0]);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
addr = reinterpret_cast<in_addr*>(address->h_addr_list[i]);
|
||||
|
||||
// if there is no nth address then return error
|
||||
if (addr == 0)
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
char* resolved_ip = inet_ntoa(*addr);
|
||||
|
||||
// check if inet_ntoa returned an error
|
||||
if (resolved_ip == NULL)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
ip.assign(resolved_ip);
|
||||
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -----------------
|
||||
|
||||
int
|
||||
ip_to_hostname (
|
||||
const std::string& ip,
|
||||
std::string& hostname
|
||||
)
|
||||
{
|
||||
// ensure that WSAStartup has been called and WSACleanup will eventually
|
||||
// be called when program ends
|
||||
sockets_startup();
|
||||
|
||||
try
|
||||
{
|
||||
// lock this mutex since gethostbyaddr isn't really thread safe
|
||||
auto_mutex M(sockets_kernel_1_mutex::startup_lock);
|
||||
|
||||
// if no ip was given then return error
|
||||
if (ip.empty())
|
||||
return OTHER_ERROR;
|
||||
|
||||
hostent* address;
|
||||
unsigned long ipnum = inet_addr(ip.c_str());
|
||||
|
||||
// if inet_addr couldn't convert ip then return an error
|
||||
if (ipnum == INADDR_NONE)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
address = gethostbyaddr(reinterpret_cast<char*>(&ipnum),4,AF_INET);
|
||||
|
||||
// check if gethostbyaddr returned an error
|
||||
if (address == 0)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
hostname.assign(address->h_name);
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// connection object
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection::
|
||||
connection(
|
||||
SOCKET_container sock,
|
||||
unsigned short foreign_port,
|
||||
const std::string& foreign_ip,
|
||||
unsigned short local_port,
|
||||
const std::string& local_ip
|
||||
) :
|
||||
user_data(0),
|
||||
connection_socket(*(new SOCKET_container())),
|
||||
connection_foreign_port(foreign_port),
|
||||
connection_foreign_ip(foreign_ip),
|
||||
connection_local_port(local_port),
|
||||
connection_local_ip(local_ip),
|
||||
sd(false),
|
||||
sdo(false),
|
||||
sdr(0)
|
||||
{
|
||||
connection_socket = sock;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection::
|
||||
~connection (
|
||||
)
|
||||
{
|
||||
if (connection_socket != INVALID_SOCKET)
|
||||
closesocket(connection_socket);
|
||||
delete &connection_socket;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int connection::
|
||||
disable_nagle()
|
||||
{
|
||||
int flag = 1;
|
||||
int status = setsockopt( connection_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) );
|
||||
|
||||
if (status == SOCKET_ERROR)
|
||||
return OTHER_ERROR;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
long connection::
|
||||
write (
|
||||
const char* buf,
|
||||
long num
|
||||
)
|
||||
{
|
||||
const long old_num = num;
|
||||
long status;
|
||||
const long max_send_length = 1024*1024*100;
|
||||
while (num > 0)
|
||||
{
|
||||
// Make sure to cap the max value num can take on so that if it is
|
||||
// really large (it might be big on 64bit platforms) so that the OS
|
||||
// can't possibly get upset about it being large.
|
||||
const long length = std::min(max_send_length, num);
|
||||
if ( (status = send(connection_socket,buf,length,0)) == SOCKET_ERROR)
|
||||
{
|
||||
if (sdo_called())
|
||||
return SHUTDOWN;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
num -= status;
|
||||
buf += status;
|
||||
}
|
||||
return old_num;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
long connection::
|
||||
read (
|
||||
char* buf,
|
||||
long num
|
||||
)
|
||||
{
|
||||
const long max_recv_length = 1024*1024*100;
|
||||
// Make sure to cap the max value num can take on so that if it is
|
||||
// really large (it might be big on 64bit platforms) so that the OS
|
||||
// can't possibly get upset about it being large.
|
||||
const long length = std::min(max_recv_length, num);
|
||||
long status = recv(connection_socket,buf,length,0);
|
||||
if (status == SOCKET_ERROR)
|
||||
{
|
||||
// if this error is the result of a shutdown call then return SHUTDOWN
|
||||
if (sd_called())
|
||||
return SHUTDOWN;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
else if (status == 0 && sd_called())
|
||||
{
|
||||
return SHUTDOWN;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
long connection::
|
||||
read (
|
||||
char* buf,
|
||||
long num,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
if (readable(timeout) == false)
|
||||
return TIMEOUT;
|
||||
|
||||
const long max_recv_length = 1024*1024*100;
|
||||
// Make sure to cap the max value num can take on so that if it is
|
||||
// really large (it might be big on 64bit platforms) so that the OS
|
||||
// can't possibly get upset about it being large.
|
||||
const long length = std::min(max_recv_length, num);
|
||||
long status = recv(connection_socket,buf,length,0);
|
||||
if (status == SOCKET_ERROR)
|
||||
{
|
||||
// if this error is the result of a shutdown call then return SHUTDOWN
|
||||
if (sd_called())
|
||||
return SHUTDOWN;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
else if (status == 0 && sd_called())
|
||||
{
|
||||
return SHUTDOWN;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
bool connection::
|
||||
readable (
|
||||
unsigned long timeout
|
||||
) const
|
||||
{
|
||||
fd_set read_set;
|
||||
// initialize read_set
|
||||
FD_ZERO(&read_set);
|
||||
|
||||
// add the listening socket to read_set
|
||||
FD_SET(connection_socket, &read_set);
|
||||
|
||||
// setup a timeval structure
|
||||
timeval time_to_wait;
|
||||
time_to_wait.tv_sec = static_cast<long>(timeout/1000);
|
||||
time_to_wait.tv_usec = static_cast<long>((timeout%1000)*1000);
|
||||
|
||||
// wait on select
|
||||
int status = select(0,&read_set,0,0,&time_to_wait);
|
||||
|
||||
// if select timed out or there was an error
|
||||
if (status <= 0)
|
||||
return false;
|
||||
|
||||
// data is ready to be read
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int connection::
|
||||
shutdown_outgoing (
|
||||
)
|
||||
{
|
||||
sd_mutex.lock();
|
||||
if (sdo || sd)
|
||||
{
|
||||
sd_mutex.unlock();
|
||||
return sdr;
|
||||
}
|
||||
sdo = true;
|
||||
sdr = ::shutdown(connection_socket,SD_SEND);
|
||||
|
||||
// convert -1 error code into the OTHER_ERROR error code
|
||||
if (sdr == -1)
|
||||
sdr = OTHER_ERROR;
|
||||
|
||||
int temp = sdr;
|
||||
|
||||
sd_mutex.unlock();
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int connection::
|
||||
shutdown (
|
||||
)
|
||||
{
|
||||
sd_mutex.lock();
|
||||
if (sd)
|
||||
{
|
||||
sd_mutex.unlock();
|
||||
return sdr;
|
||||
}
|
||||
sd = true;
|
||||
SOCKET stemp = connection_socket;
|
||||
connection_socket = INVALID_SOCKET;
|
||||
sdr = closesocket(stemp);
|
||||
|
||||
// convert SOCKET_ERROR error code into the OTHER_ERROR error code
|
||||
if (sdr == SOCKET_ERROR)
|
||||
sdr = OTHER_ERROR;
|
||||
|
||||
int temp = sdr;
|
||||
|
||||
sd_mutex.unlock();
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
connection::socket_descriptor_type connection::
|
||||
get_socket_descriptor (
|
||||
) const
|
||||
{
|
||||
return connection_socket.val;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// listener object
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
listener::
|
||||
listener(
|
||||
SOCKET_container sock,
|
||||
unsigned short port,
|
||||
const std::string& ip
|
||||
) :
|
||||
listening_socket(*(new SOCKET_container)),
|
||||
listening_port(port),
|
||||
listening_ip(ip),
|
||||
inaddr_any(listening_ip.empty())
|
||||
{
|
||||
listening_socket = sock;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
listener::
|
||||
~listener (
|
||||
)
|
||||
{
|
||||
closesocket(listening_socket);
|
||||
delete &listening_socket;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int listener::
|
||||
accept (
|
||||
scoped_ptr<connection>& new_connection,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
new_connection.reset(0);
|
||||
connection* con;
|
||||
int status = this->accept(con, timeout);
|
||||
|
||||
if (status == 0)
|
||||
new_connection.reset(con);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int listener::
|
||||
accept (
|
||||
connection*& new_connection,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
SOCKET incoming;
|
||||
sockaddr_in incomingAddr;
|
||||
int length = sizeof(sockaddr_in);
|
||||
|
||||
// implement timeout with select if timeout is > 0
|
||||
if (timeout > 0)
|
||||
{
|
||||
fd_set read_set;
|
||||
// initialize read_set
|
||||
FD_ZERO(&read_set);
|
||||
|
||||
// add the listening socket to read_set
|
||||
FD_SET(listening_socket, &read_set);
|
||||
|
||||
// setup a timeval structure
|
||||
timeval time_to_wait;
|
||||
time_to_wait.tv_sec = static_cast<long>(timeout/1000);
|
||||
time_to_wait.tv_usec = static_cast<long>((timeout%1000)*1000);
|
||||
|
||||
|
||||
// wait on select
|
||||
int status = select(0,&read_set,0,0,&time_to_wait);
|
||||
|
||||
// if select timed out
|
||||
if (status == 0)
|
||||
return TIMEOUT;
|
||||
|
||||
// if select returned an error
|
||||
if (status == SOCKET_ERROR)
|
||||
return OTHER_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// call accept to get a new connection
|
||||
incoming=::accept(listening_socket,reinterpret_cast<sockaddr*>(&incomingAddr),&length);
|
||||
|
||||
// if there was an error return OTHER_ERROR
|
||||
if ( incoming == INVALID_SOCKET )
|
||||
return OTHER_ERROR;
|
||||
|
||||
|
||||
// get the port of the foreign host into foreign_port
|
||||
int foreign_port = ntohs(incomingAddr.sin_port);
|
||||
|
||||
// get the IP of the foreign host into foreign_ip
|
||||
std::string foreign_ip;
|
||||
{
|
||||
char* foreign_ip_temp = inet_ntoa(incomingAddr.sin_addr);
|
||||
|
||||
// check if inet_ntoa() returned an error
|
||||
if (foreign_ip_temp == NULL)
|
||||
{
|
||||
closesocket(incoming);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
foreign_ip.assign(foreign_ip_temp);
|
||||
}
|
||||
|
||||
|
||||
// get the local ip
|
||||
std::string local_ip;
|
||||
if (inaddr_any == true)
|
||||
{
|
||||
sockaddr_in local_info;
|
||||
length = sizeof(sockaddr_in);
|
||||
// get the local sockaddr_in structure associated with this new connection
|
||||
if ( getsockname (
|
||||
incoming,
|
||||
reinterpret_cast<sockaddr*>(&local_info),
|
||||
&length
|
||||
) == SOCKET_ERROR
|
||||
)
|
||||
{ // an error occurred
|
||||
closesocket(incoming);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
char* temp = inet_ntoa(local_info.sin_addr);
|
||||
|
||||
// check if inet_ntoa() returned an error
|
||||
if (temp == NULL)
|
||||
{
|
||||
closesocket(incoming);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
local_ip.assign(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
local_ip = listening_ip;
|
||||
}
|
||||
|
||||
|
||||
// set the SO_OOBINLINE option
|
||||
int flag_value = 1;
|
||||
if (setsockopt(incoming,SOL_SOCKET,SO_OOBINLINE,reinterpret_cast<const char*>(&flag_value),sizeof(int)) == SOCKET_ERROR )
|
||||
{
|
||||
closesocket(incoming);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// make a new connection object for this new connection
|
||||
try
|
||||
{
|
||||
new_connection = new connection (
|
||||
incoming,
|
||||
foreign_port,
|
||||
foreign_ip,
|
||||
listening_port,
|
||||
local_ip
|
||||
);
|
||||
}
|
||||
catch (...) { closesocket(incoming); return OTHER_ERROR; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// socket creation functions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int create_listener (
|
||||
scoped_ptr<listener>& new_listener,
|
||||
unsigned short port,
|
||||
const std::string& ip
|
||||
)
|
||||
{
|
||||
new_listener.reset();
|
||||
listener* temp;
|
||||
int status = create_listener(temp,port,ip);
|
||||
|
||||
if (status == 0)
|
||||
new_listener.reset(temp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int create_listener (
|
||||
listener*& new_listener,
|
||||
unsigned short port,
|
||||
const std::string& ip
|
||||
)
|
||||
{
|
||||
// ensure that WSAStartup has been called and WSACleanup will eventually
|
||||
// be called when program ends
|
||||
sockets_startup();
|
||||
|
||||
sockaddr_in sa; // local socket structure
|
||||
ZeroMemory(&sa,sizeof(sockaddr_in)); // initialize sa
|
||||
|
||||
SOCKET sock = socket (AF_INET, SOCK_STREAM, 0); // get a new socket
|
||||
|
||||
// if socket() returned an error then return OTHER_ERROR
|
||||
if (sock == INVALID_SOCKET )
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
// set the local socket structure
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(port);
|
||||
if (ip.empty())
|
||||
{
|
||||
// if the listener should listen on any IP
|
||||
sa.sin_addr.S_un.S_addr = htons(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is a specific ip to listen on
|
||||
sa.sin_addr.S_un.S_addr = inet_addr(ip.c_str());
|
||||
// if inet_addr couldn't convert the ip then return an error
|
||||
if ( sa.sin_addr.S_un.S_addr == INADDR_NONE )
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// set the SO_REUSEADDR option
|
||||
int flag_value = 1;
|
||||
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,reinterpret_cast<const char*>(&flag_value),sizeof(int));
|
||||
|
||||
// bind the new socket to the requested port and ip
|
||||
if (bind(sock,reinterpret_cast<sockaddr*>(&sa),sizeof(sockaddr_in))==SOCKET_ERROR)
|
||||
{
|
||||
const int err = WSAGetLastError();
|
||||
// if there was an error
|
||||
closesocket(sock);
|
||||
|
||||
// if the port is already bound then return PORTINUSE
|
||||
if (err == WSAEADDRINUSE)
|
||||
return PORTINUSE;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// tell the new socket to listen
|
||||
if ( listen(sock,SOMAXCONN) == SOCKET_ERROR)
|
||||
{
|
||||
const int err = WSAGetLastError();
|
||||
// if there was an error return OTHER_ERROR
|
||||
closesocket(sock);
|
||||
|
||||
// if the port is already bound then return PORTINUSE
|
||||
if (err == WSAEADDRINUSE)
|
||||
return PORTINUSE;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
// determine the port used if necessary
|
||||
if (port == 0)
|
||||
{
|
||||
sockaddr_in local_info;
|
||||
int length = sizeof(sockaddr_in);
|
||||
if ( getsockname (
|
||||
sock,
|
||||
reinterpret_cast<sockaddr*>(&local_info),
|
||||
&length
|
||||
) == SOCKET_ERROR
|
||||
)
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
port = ntohs(local_info.sin_port);
|
||||
}
|
||||
|
||||
|
||||
// initialize a listener object on the heap with the new socket
|
||||
try { new_listener = new listener(sock,port,ip); }
|
||||
catch(...) { closesocket(sock); return OTHER_ERROR; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int create_connection (
|
||||
scoped_ptr<connection>& new_connection,
|
||||
unsigned short foreign_port,
|
||||
const std::string& foreign_ip,
|
||||
unsigned short local_port,
|
||||
const std::string& local_ip
|
||||
)
|
||||
{
|
||||
new_connection.reset();
|
||||
connection* temp;
|
||||
int status = create_connection(temp,foreign_port, foreign_ip, local_port, local_ip);
|
||||
|
||||
if (status == 0)
|
||||
new_connection.reset(temp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int create_connection (
|
||||
connection*& new_connection,
|
||||
unsigned short foreign_port,
|
||||
const std::string& foreign_ip,
|
||||
unsigned short local_port,
|
||||
const std::string& local_ip
|
||||
)
|
||||
{
|
||||
// ensure that WSAStartup has been called and WSACleanup
|
||||
// will eventually be called when program ends
|
||||
sockets_startup();
|
||||
|
||||
|
||||
sockaddr_in local_sa; // local socket structure
|
||||
sockaddr_in foreign_sa; // foreign socket structure
|
||||
ZeroMemory(&local_sa,sizeof(sockaddr_in)); // initialize local_sa
|
||||
ZeroMemory(&foreign_sa,sizeof(sockaddr_in)); // initialize foreign_sa
|
||||
|
||||
int length;
|
||||
|
||||
SOCKET sock = socket (AF_INET, SOCK_STREAM, 0); // get a new socket
|
||||
|
||||
// if socket() returned an error then return OTHER_ERROR
|
||||
if (sock == INVALID_SOCKET )
|
||||
{
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
// set the foreign socket structure
|
||||
foreign_sa.sin_family = AF_INET;
|
||||
foreign_sa.sin_port = htons(foreign_port);
|
||||
foreign_sa.sin_addr.S_un.S_addr = inet_addr(foreign_ip.c_str());
|
||||
|
||||
// if inet_addr couldn't convert the ip then return an error
|
||||
if ( foreign_sa.sin_addr.S_un.S_addr == INADDR_NONE )
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// set up the local socket structure
|
||||
local_sa.sin_family = AF_INET;
|
||||
|
||||
// set the local ip
|
||||
if (local_ip.empty())
|
||||
{
|
||||
// if the listener should listen on any IP
|
||||
local_sa.sin_addr.S_un.S_addr = htons(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is a specific ip to listen on
|
||||
local_sa.sin_addr.S_un.S_addr = inet_addr(local_ip.c_str());
|
||||
|
||||
// if inet_addr couldn't convert the ip then return an error
|
||||
if (local_sa.sin_addr.S_un.S_addr == INADDR_NONE)
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// set the local port
|
||||
local_sa.sin_port = htons(local_port);
|
||||
|
||||
|
||||
|
||||
// bind the new socket to the requested local port and local ip
|
||||
if ( bind (
|
||||
sock,
|
||||
reinterpret_cast<sockaddr*>(&local_sa),
|
||||
sizeof(sockaddr_in)
|
||||
) == SOCKET_ERROR
|
||||
)
|
||||
{
|
||||
const int err = WSAGetLastError();
|
||||
// if there was an error
|
||||
closesocket(sock);
|
||||
|
||||
// if the port is already bound then return PORTINUSE
|
||||
if (err == WSAEADDRINUSE)
|
||||
return PORTINUSE;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
// connect the socket
|
||||
if (connect (
|
||||
sock,
|
||||
reinterpret_cast<sockaddr*>(&foreign_sa),
|
||||
sizeof(sockaddr_in)
|
||||
) == SOCKET_ERROR
|
||||
)
|
||||
{
|
||||
const int err = WSAGetLastError();
|
||||
closesocket(sock);
|
||||
// if the port is already bound then return PORTINUSE
|
||||
if (err == WSAEADDRINUSE)
|
||||
return PORTINUSE;
|
||||
else
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// determine the local port and IP and store them in used_local_ip
|
||||
// and used_local_port
|
||||
int used_local_port;
|
||||
std::string used_local_ip;
|
||||
sockaddr_in local_info;
|
||||
if (local_port == 0)
|
||||
{
|
||||
length = sizeof(sockaddr_in);
|
||||
if (getsockname (
|
||||
sock,
|
||||
reinterpret_cast<sockaddr*>(&local_info),
|
||||
&length
|
||||
) == SOCKET_ERROR
|
||||
)
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
used_local_port = ntohs(local_info.sin_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
used_local_port = local_port;
|
||||
}
|
||||
|
||||
// determine real local ip
|
||||
if (local_ip.empty())
|
||||
{
|
||||
// if local_port is not 0 then we must fill the local_info structure
|
||||
if (local_port != 0)
|
||||
{
|
||||
length = sizeof(sockaddr_in);
|
||||
if ( getsockname (
|
||||
sock,
|
||||
reinterpret_cast<sockaddr*>(&local_info),
|
||||
&length
|
||||
) == SOCKET_ERROR
|
||||
)
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
char* temp = inet_ntoa(local_info.sin_addr);
|
||||
|
||||
// check if inet_ntoa returned an error
|
||||
if (temp == NULL)
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
used_local_ip.assign(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
used_local_ip = local_ip;
|
||||
}
|
||||
|
||||
// set the SO_OOBINLINE option
|
||||
int flag_value = 1;
|
||||
if (setsockopt(sock,SOL_SOCKET,SO_OOBINLINE,reinterpret_cast<const char*>(&flag_value),sizeof(int)) == SOCKET_ERROR )
|
||||
{
|
||||
closesocket(sock);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
|
||||
// initialize a connection object on the heap with the new socket
|
||||
try
|
||||
{
|
||||
new_connection = new connection (
|
||||
sock,
|
||||
foreign_port,
|
||||
foreign_ip,
|
||||
used_local_port,
|
||||
used_local_ip
|
||||
);
|
||||
}
|
||||
catch(...) {closesocket(sock); return OTHER_ERROR; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
#endif // DLIB_SOCKETS_KERNEL_1_CPp_
|
||||
|
||||
350
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_1.h
vendored
Normal file
350
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_1.h
vendored
Normal file
@@ -0,0 +1,350 @@
|
||||
// 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 "../algs.h"
|
||||
#include <string>
|
||||
#include "../threads.h"
|
||||
#include "../smart_pointers.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 (
|
||||
scoped_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 (
|
||||
scoped_ptr<listener>& new_listener,
|
||||
unsigned short port,
|
||||
const std::string& ip = ""
|
||||
);
|
||||
|
||||
int create_connection (
|
||||
scoped_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_
|
||||
|
||||
1109
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_2.cpp
vendored
Normal file
1109
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_2.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
393
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_2.h
vendored
Normal file
393
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_2.h
vendored
Normal file
@@ -0,0 +1,393 @@
|
||||
// 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 <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <ctime>
|
||||
#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 <string>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "../threads.h"
|
||||
#include "../algs.h"
|
||||
#include "../smart_pointers.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 (
|
||||
scoped_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 (
|
||||
scoped_ptr<listener>& new_listener,
|
||||
unsigned short port,
|
||||
const std::string& ip = ""
|
||||
);
|
||||
|
||||
int create_connection (
|
||||
scoped_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_
|
||||
|
||||
495
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_abstract.h
vendored
Normal file
495
lib/3rdParty/dlib/include/dlib/sockets/sockets_kernel_abstract.h
vendored
Normal file
@@ -0,0 +1,495 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SOCKETS_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_SOCKETS_KERNEl_ABSTRACT_
|
||||
|
||||
#include <string>
|
||||
#include "../threads.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
GENERAL COMMENTS:
|
||||
Nothing in here will throw exceptions.
|
||||
|
||||
All ip address strings in this file refer to IPv4 addresses. For
|
||||
example "192.168.1.1"
|
||||
|
||||
Timeouts:
|
||||
All timeout values are measured in milliseconds but you are not
|
||||
guaranteed to have that level of resolution. The actual resolution
|
||||
is implementation defined.
|
||||
|
||||
GENERAL WARNING
|
||||
Don't call any of these functions or make any of these objects
|
||||
before main() has been entered.
|
||||
|
||||
EXCEPTIONS
|
||||
Unless specified otherwise, nothing in this file throws exceptions.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// LOOKUP FUNCTIONS
|
||||
|
||||
// all lookup functions are thread-safe
|
||||
|
||||
int get_local_hostname (
|
||||
std::string& hostname
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (#get_local_hostname() == 0) then
|
||||
- #hostname == a string containing the hostname of the local computer
|
||||
|
||||
- returns 0 upon success
|
||||
- returns OTHER_ERROR upon failure and in this case #hostname's value
|
||||
is undefined
|
||||
!*/
|
||||
|
||||
// -----------------
|
||||
|
||||
int hostname_to_ip (
|
||||
const std::string& hostname,
|
||||
std::string& ip,
|
||||
int n = 0
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- n >= 0
|
||||
ensures
|
||||
- if (#hostname_to_ip() == 0) then
|
||||
- #ip == string containing the nth ip address associated with the hostname
|
||||
|
||||
- returns 0 upon success
|
||||
- returns OTHER_ERROR upon failure
|
||||
!*/
|
||||
|
||||
// -----------------
|
||||
|
||||
int ip_to_hostname (
|
||||
const std::string& ip,
|
||||
std::string& hostname
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (#ip_to_hostname() == 0) then
|
||||
- #hostname == string containing the hostname associated with ip
|
||||
|
||||
- returns 0 upon success
|
||||
- returns OTHER_ERROR upon failure
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
//
|
||||
// socket creation functions
|
||||
//
|
||||
// The following functions are guaranteed to be thread-safe
|
||||
//
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
int create_listener (
|
||||
listener*& new_listener,
|
||||
unsigned short port,
|
||||
const std::string& ip = ""
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- 0 <= port <= 65535
|
||||
ensures
|
||||
- if (#create_listener() == 0) then
|
||||
- #new_listener == a pointer to a listener object that is listening on
|
||||
the specified port and ip for an incoming connection
|
||||
- if (ip == "") then
|
||||
- the new listener will be listening on all interfaces
|
||||
- if (port == 0) then
|
||||
- the operating system will assign a free port to listen on
|
||||
|
||||
|
||||
- returns 0 if create_listener was successful
|
||||
- returns PORTINUSE if the specified local port was already in use
|
||||
- returns OTHER_ERROR if some other error occurred
|
||||
!*/
|
||||
|
||||
int create_listener (
|
||||
scoped_ptr<listener>& new_listener,
|
||||
unsigned short port,
|
||||
const std::string& ip = ""
|
||||
);
|
||||
/*!
|
||||
This function is just an overload of the above function but it gives you a
|
||||
scoped_ptr smart pointer instead of a C pointer.
|
||||
!*/
|
||||
|
||||
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 = ""
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- 0 < foreign_port <= 65535
|
||||
- 0 <= local_port <= 65535
|
||||
ensures
|
||||
- if (#create_connection() == 0) then
|
||||
- #new_connection == a pointer to a connection object that is connected
|
||||
to foreign_ip on port foreign_port and is using the local interface
|
||||
local_ip and local port local_port
|
||||
- #new_connection->user_data == 0
|
||||
- if (local_ip == "") then
|
||||
- the operating system will chose this for you
|
||||
- if (local_port == 0) then
|
||||
- the operating system will chose this for you
|
||||
|
||||
- returns 0 if create_connection was successful
|
||||
- returns PORTINUSE if the specified local port was already in use
|
||||
- returns OTHER_ERROR if some other error occurred
|
||||
!*/
|
||||
|
||||
int create_connection (
|
||||
scoped_ptr<connection>& new_connection,
|
||||
unsigned short foreign_port,
|
||||
const std::string& foreign_ip,
|
||||
unsigned short local_port = 0,
|
||||
const std::string& local_ip = ""
|
||||
);
|
||||
/*!
|
||||
This function is just an overload of the above function but it gives you a
|
||||
scoped_ptr smart pointer instead of a C pointer.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// connection object
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class connection
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a TCP connection.
|
||||
|
||||
Instances of this class can only be created by using the
|
||||
create_connection function or listener class defined below.
|
||||
|
||||
NOTE:
|
||||
A connection object must ALWAYS be closed (delete the pointer to the
|
||||
connection) or it will cause a resource leak.
|
||||
|
||||
Note also that all errors indicated by a return code of OTHER_ERROR
|
||||
are fatal so if one occurs the connection should just be closed.
|
||||
|
||||
CLOSING A CONNECTION
|
||||
Note that if ~connection() or shutdown() is called before the remote client
|
||||
has received all sent data it is possible that the data will be lost. To
|
||||
avoid this you should call the close_gracefully() function to close your
|
||||
connections (unless you actually do want to immediately dispose of a
|
||||
connection and don't care about the data).
|
||||
(example: close_gracefully(con); // close con gracefully but force it closed
|
||||
// if it takes more than 500 milliseconds.)
|
||||
|
||||
THREAD SAFETY
|
||||
- It is always safe to call shutdown() or shutdown_outgoing().
|
||||
- you may NOT call any function more than once at a time (except the
|
||||
shutdown functions).
|
||||
- do not call read() more than once at a time
|
||||
- do not call write() more than once at a time
|
||||
- You can safely call shutdown or shutdown_outgoing in conjunction with
|
||||
the read/write functions.
|
||||
This is helpful if you want to unblock another thread that is
|
||||
blocking on a read/write operation. Shutting down the connection
|
||||
will cause the read/write functions to return a value of SHUTDOWN.
|
||||
|
||||
OUT-OF-BAND DATA:
|
||||
All out-of-band data will be put inline into the normal data stream.
|
||||
This means that you can read any out-of-band data via calls to read().
|
||||
(i.e. the SO_OOBINLINE socket option will be set)
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
~connection (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- no other threads are using this connection object
|
||||
ensures
|
||||
- closes the connection (this is an abrupt non-graceful close)
|
||||
- frees the resources used by this object
|
||||
!*/
|
||||
|
||||
void* user_data;
|
||||
/*!
|
||||
This pointer is provided so that the client programmer may easily associate
|
||||
some data with a connection object. You can really do whatever you want
|
||||
with it. Initially user_data is 0.
|
||||
!*/
|
||||
|
||||
long write (
|
||||
const char* buf,
|
||||
long num
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- num > 0
|
||||
- buf points to an array of at least num bytes
|
||||
ensures
|
||||
- will block until ONE of the following occurrs:
|
||||
- num bytes from buf have been written to the connection
|
||||
- an error has occurred
|
||||
- the outgoing channel of the connection has been shutdown locally
|
||||
|
||||
- returns num if write succeeded
|
||||
- returns OTHER_ERROR if there was an error (this could be due to a
|
||||
connection close)
|
||||
- returns SHUTDOWN if the outgoing channel of the connection has been
|
||||
shutdown locally
|
||||
!*/
|
||||
|
||||
long read (
|
||||
char* buf,
|
||||
long num
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- num > 0
|
||||
- buf points to an array of at least num bytes
|
||||
ensures
|
||||
- read() will not read more than num bytes of data into #buf
|
||||
- read blocks until ONE of the following happens:
|
||||
- there is some data available and it has been written into #buf
|
||||
- the remote end of the connection is closed
|
||||
- an error has occurred
|
||||
- the connection has been shutdown locally
|
||||
|
||||
- returns the number of bytes read into #buf if there was any data.
|
||||
- returns 0 if the connection has ended/terminated and there is no more data.
|
||||
- returns OTHER_ERROR if there was an error.
|
||||
- returns SHUTDOWN if the connection has been shutdown locally
|
||||
!*/
|
||||
|
||||
long read (
|
||||
char* buf,
|
||||
long num,
|
||||
unsigned long timeout
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- num > 0
|
||||
- buf points to an array of at least num bytes
|
||||
- timeout < 2000000
|
||||
ensures
|
||||
- read() will not read more than num bytes of data into #buf
|
||||
- if (timeout > 0) then read() blocks until ONE of the following happens:
|
||||
- there is some data available and it has been written into #buf
|
||||
- the remote end of the connection is closed
|
||||
- an error has occurred
|
||||
- the connection has been shutdown locally
|
||||
- timeout milliseconds has elapsed
|
||||
- else
|
||||
- read() does not block
|
||||
|
||||
- returns the number of bytes read into #buf if there was any data.
|
||||
- returns 0 if the connection has ended/terminated and there is no more data.
|
||||
- returns TIMEOUT if timeout milliseconds elapsed before we got any data.
|
||||
- returns OTHER_ERROR if there was an error.
|
||||
- returns SHUTDOWN if the connection has been shutdown locally
|
||||
!*/
|
||||
|
||||
unsigned short get_local_port (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the local port number for this connection
|
||||
!*/
|
||||
|
||||
unsigned short get_foreign_port (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the foreign port number for this connection
|
||||
!*/
|
||||
|
||||
const std::string& get_local_ip (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the IP of the local interface this connection is using
|
||||
!*/
|
||||
|
||||
const std::string& get_foreign_ip (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the IP of the foreign host for this connection
|
||||
!*/
|
||||
|
||||
int shutdown (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (#shutdown() == 0 && connection was still open) then
|
||||
- terminates the connection but does not free the resources for the
|
||||
connection object
|
||||
|
||||
- any read() or write() calls on this connection will return immediately
|
||||
with the code SHUTDOWN.
|
||||
|
||||
- returns 0 upon success
|
||||
- returns OTHER_ERROR if there was an error
|
||||
!*/
|
||||
|
||||
int shutdown_outgoing (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (#shutdown_outgoing() == 0 && outgoing channel was still open) then
|
||||
- sends a FIN to indicate that no more data will be sent on this
|
||||
connection but leaves the receive half of the connection open to
|
||||
receive more data from the other host
|
||||
|
||||
- any calls to write() will return immediately with the code SHUTDOWN.
|
||||
|
||||
- returns 0 upon success
|
||||
- returns OTHER_ERROR if there was an error
|
||||
!*/
|
||||
|
||||
int disable_nagle(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- Sets the TCP_NODELAY socket option to disable Nagle's algorithm.
|
||||
This can sometimes reduce transmission latency, however, in almost
|
||||
all normal cases you don't want to mess with this as the default
|
||||
setting is usually appropriate.
|
||||
|
||||
- returns 0 upon success
|
||||
- returns OTHER_ERROR if there was an error
|
||||
!*/
|
||||
|
||||
typedef platform_specific_type socket_descriptor_type;
|
||||
socket_descriptor_type get_socket_descriptor (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the underlying socket descriptor for this connection
|
||||
object. The reason you might want access to this is to
|
||||
pass it to some other library that requires a socket file
|
||||
descriptor. However, if you do this then you probably shouldn't
|
||||
use the dlib::connection read() and write() anymore since
|
||||
whatever you are doing with the socket descriptor is probably
|
||||
doing I/O with the socket.
|
||||
!*/
|
||||
|
||||
private:
|
||||
// restricted functions
|
||||
connection();
|
||||
connection(connection&); // copy constructor
|
||||
connection& operator=(connection&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// listener object
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class listener
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a TCP socket waiting for incoming connections.
|
||||
Calling accept returns a pointer to any new incoming connections on its
|
||||
port.
|
||||
|
||||
Instances of this class can only be created by using the
|
||||
create_listener function defined below.
|
||||
|
||||
NOTE:
|
||||
A listener object must ALWAYS be closed (delete the pointer to it) or
|
||||
it will cause a resource leak.
|
||||
|
||||
Note also that all errors indicated by a return code of OTHER_ERROR
|
||||
are fatal so if one occurs the listener should be closed.
|
||||
|
||||
THREAD SAFETY
|
||||
None of the functions in this object are guaranteed to be thread-safe.
|
||||
This means that you must serialize all access to this object.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
~listener (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- no other threads are using this listener object
|
||||
ensures
|
||||
- closes the listener
|
||||
- frees the resources used by this object
|
||||
!*/
|
||||
|
||||
int accept (
|
||||
connection*& new_connection,
|
||||
unsigned long timeout = 0
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- timeout < 2000000
|
||||
ensures
|
||||
- blocks until a new connection is ready or timeout milliseconds have
|
||||
elapsed.
|
||||
- #new_connection == a pointer to the new connection object
|
||||
- #new_connection->user_data == 0
|
||||
- if (timeout == 0) then
|
||||
- the timeout argument is ignored
|
||||
|
||||
- returns 0 if accept() was successful
|
||||
- returns TIMEOUT if timeout milliseconds have elapsed
|
||||
- returns OTHER_ERROR if an error has occurred
|
||||
!*/
|
||||
|
||||
int accept (
|
||||
scoped_ptr<connection>& new_connection,
|
||||
unsigned long timeout = 0
|
||||
);
|
||||
/*!
|
||||
This function is just an overload of the above function but it gives you a
|
||||
scoped_ptr smart pointer instead of a C pointer.
|
||||
!*/
|
||||
|
||||
unsigned short get_listening_port (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the port number that this object is listening on
|
||||
!*/
|
||||
|
||||
const std::string& get_listening_ip (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns a string containing the IP (e.g. "127.0.0.1") of the
|
||||
interface this object is listening on
|
||||
- returns "" if it is accepting connections on all interfaces
|
||||
!*/
|
||||
|
||||
private:
|
||||
// restricted functions
|
||||
listener();
|
||||
listener(listener&); // copy constructor
|
||||
listener& operator=(listener&); // assignment operator
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_SOCKETS_KERNEl_ABSTRACT_
|
||||
|
||||
6
lib/3rdParty/dlib/include/dlib/sockets/windows.h
vendored
Normal file
6
lib/3rdParty/dlib/include/dlib/sockets/windows.h
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SOCKETS_KERNEl_2_
|
||||
#include "sockets_kernel_1.h"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user