Updating dlib and linking to it differently, increasing compilation speed and reducing dependency issues with it.

This commit is contained in:
Tadas Baltrusaitis
2018-06-08 16:48:21 +01:00
parent 8bcc5c46ca
commit cd24af000f
724 changed files with 91433 additions and 92254 deletions

View File

@@ -1,341 +0,0 @@
// 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

View File

@@ -3,11 +3,14 @@
#ifndef DLIB_SOCKETS_EXTENSIONs_
#define DLIB_SOCKETS_EXTENSIONs_
#include <string>
#include "../sockets.h"
#include "sockets_extensions_abstract.h"
#include "../smart_pointers.h"
#include <iosfwd>
#include <memory>
#include <string>
#include "../sockets.h"
#include "../smart_pointers/scoped_ptr.h"
#include "sockets_extensions_abstract.h"
namespace dlib
{
@@ -132,7 +135,7 @@ namespace dlib
// ----------------------------------------------------------------------------------------
void close_gracefully (
scoped_ptr<connection>& con,
std::unique_ptr<connection>& con,
unsigned long timeout = 500
);

View File

@@ -3,9 +3,10 @@
#undef DLIB_SOCKETS_EXTENSIONs_ABSTRACT_
#ifdef DLIB_SOCKETS_EXTENSIONs_ABSTRACT_
#include <memory>
#include <string>
#include "sockets_kernel_abstract.h"
#include "../smart_pointers.h"
#include "../error.h"
namespace dlib
@@ -265,7 +266,7 @@ namespace dlib
// ----------------------------------------------------------------------------------------
void close_gracefully (
scoped_ptr<connection>& con,
std::unique_ptr<connection>& con,
unsigned long timeout = 500
);
/*!

View File

@@ -1,978 +0,0 @@
// 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_

View File

@@ -9,10 +9,11 @@
#include "sockets_kernel_abstract.h"
#include "../algs.h"
#include <memory>
#include <string>
#include "../algs.h"
#include "../threads.h"
#include "../smart_pointers.h"
#include "../uintn.h"
@@ -269,7 +270,7 @@ namespace dlib
);
int accept (
scoped_ptr<connection>& new_connection,
std::unique_ptr<connection>& new_connection,
unsigned long timeout = 0
);
@@ -324,13 +325,13 @@ namespace dlib
);
int create_listener (
scoped_ptr<listener>& new_listener,
std::unique_ptr<listener>& new_listener,
unsigned short port,
const std::string& ip = ""
);
int create_connection (
scoped_ptr<connection>& new_connection,
std::unique_ptr<connection>& new_connection,
unsigned short foreign_port,
const std::string& foreign_ip,
unsigned short local_port = 0,

File diff suppressed because it is too large Load Diff

View File

@@ -13,10 +13,14 @@
#define _BSD_SOCKLEN_T_
#include <ctime>
#include <memory>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <ctime>
#ifndef HPUX
#include <sys/select.h>
#endif
@@ -26,13 +30,12 @@
#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"
@@ -312,7 +315,7 @@ namespace dlib
);
int accept (
scoped_ptr<connection>& new_connection,
std::unique_ptr<connection>& new_connection,
unsigned long timeout = 0
);
@@ -368,13 +371,13 @@ namespace dlib
);
int create_listener (
scoped_ptr<listener>& new_listener,
std::unique_ptr<listener>& new_listener,
unsigned short port,
const std::string& ip = ""
);
int create_connection (
scoped_ptr<connection>& new_connection,
std::unique_ptr<connection>& new_connection,
unsigned short foreign_port,
const std::string& foreign_ip,
unsigned short local_port = 0,

View File

@@ -117,13 +117,13 @@ namespace dlib
!*/
int create_listener (
scoped_ptr<listener>& new_listener,
std::unique_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.
std::unique_ptr smart pointer instead of a C pointer.
!*/
int create_connection (
@@ -154,7 +154,7 @@ namespace dlib
!*/
int create_connection (
scoped_ptr<connection>& new_connection,
std::unique_ptr<connection>& new_connection,
unsigned short foreign_port,
const std::string& foreign_ip,
unsigned short local_port = 0,
@@ -162,7 +162,7 @@ namespace dlib
);
/*!
This function is just an overload of the above function but it gives you a
scoped_ptr smart pointer instead of a C pointer.
std::unique_ptr smart pointer instead of a C pointer.
!*/
// ----------------------------------------------------------------------------------------
@@ -242,7 +242,7 @@ namespace dlib
- num > 0
- buf points to an array of at least num bytes
ensures
- will block until ONE of the following occurrs:
- will block until ONE of the following occurs:
- num bytes from buf have been written to the connection
- an error has occurred
- the outgoing channel of the connection has been shutdown locally
@@ -459,12 +459,12 @@ namespace dlib
!*/
int accept (
scoped_ptr<connection>& new_connection,
std::unique_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.
std::unique_ptr smart pointer instead of a C pointer.
!*/
unsigned short get_listening_port (