// 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 #include #include #include #include #include #ifndef HPUX #include #endif #include #include #include #include #include #include #include #include "../threads.h" #include "../algs.h" namespace dlib { // ---------------------------------------------------------------------------------------- // forward declarations class socket_factory; class listener; // ---------------------------------------------------------------------------------------- // lookup functions int get_local_hostname ( std::string& hostname ); // ----------------- int hostname_to_ip ( const std::string& hostname, std::string& ip, int n = 0 ); // ----------------- int ip_to_hostname ( const std::string& ip, std::string& hostname ); // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // connection object // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- class connection { /*! INITIAL_VALUE sd == false sdo == false sdr == 0 CONVENTION connection_socket == the socket handle for this connection. connection_foreign_port == the port that foreign host is using for this connection connection_foreign_ip == a string containing the IP address of the foreign host connection_local_port == the port that the local host is using for this connection connection_local_ip == a string containing the IP address of the local interface being used by this connection sd == if shutdown() has been called then true else false sdo == if shutdown_outgoing() has been called then true else false sdr == the return value of shutdown() if it has been called. if it hasn't been called then 0 !*/ friend class listener; // make listener a friend of connection // make create_connection a friend of connection friend int create_connection ( connection*& new_connection, unsigned short foreign_port, const std::string& foreign_ip, unsigned short local_port, const std::string& local_ip ); public: ~connection(); void* user_data; long write ( const char* buf, long num ); long read ( char* buf, long num ); long read ( char* buf, long num, unsigned long timeout ); int get_local_port ( ) const { return connection_local_port; } int get_foreign_port ( ) const { return connection_foreign_port; } const std::string& get_local_ip ( ) const { return connection_local_ip; } const std::string& get_foreign_ip ( ) const { return connection_foreign_ip; } int shutdown_outgoing ( ) { sd_mutex.lock(); if (sdo || sd) { sd_mutex.unlock(); return sdr; } sdo = true; sdr = ::shutdown(connection_socket,SHUT_WR); int temp = sdr; sd_mutex.unlock(); return temp; } int shutdown ( ) { sd_mutex.lock(); if (sd) { sd_mutex.unlock(); return sdr; } sd = true; sdr = ::shutdown(connection_socket,SHUT_RDWR); int temp = sdr; sd_mutex.unlock(); return temp; } int disable_nagle( ); typedef int socket_descriptor_type; socket_descriptor_type get_socket_descriptor ( ) const { return connection_socket; } private: bool readable ( unsigned long timeout ) const; /*! requires - timeout < 2000000 ensures - returns true if a read call on this connection will not block. - returns false if a read call on this connection will block or if there was an error. !*/ bool sd_called ( )const /*! ensures - returns true if shutdown() has been called else - returns false !*/ { sd_mutex.lock(); bool temp = sd; sd_mutex.unlock(); return temp; } bool sdo_called ( )const /*! ensures - returns true if shutdown_outgoing() or shutdown() has been called else returns false !*/ { sd_mutex.lock(); bool temp = false; if (sdo || sd) temp = true; sd_mutex.unlock(); return temp; } // data members int connection_socket; const int connection_foreign_port; const std::string connection_foreign_ip; const int connection_local_port; const std::string connection_local_ip; bool sd; // called shutdown bool sdo; // called shutdown_outgoing int sdr; // return value for shutdown mutex sd_mutex; // a lock for the three above vars connection( int sock, int foreign_port, const std::string& foreign_ip, int local_port, const std::string& local_ip ); /*! requires - sock is a socket handle - sock is the handle for the connection between foreign_ip:foreign_port and local_ip:local_port ensures - *this is initialized correctly with the above parameters !*/ // restricted functions connection(); connection(connection&); // copy constructor connection& operator=(connection&); // assignement opertor }; // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // listener object // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- class listener { /*! CONVENTION if (inaddr_any == false) { listening_ip == a string containing the address the listener is listening on } else { the listener is listening on all interfaces } listening_port == the port the listener is listening on listening_socket == the listening socket handle for this object !*/ // make the create_listener a friend of listener friend int create_listener ( listener*& new_listener, unsigned short port, const std::string& ip ); public: ~listener(); int accept ( connection*& new_connection, unsigned long timeout = 0 ); int accept ( std::unique_ptr& new_connection, unsigned long timeout = 0 ); int get_listening_port ( ) const { return listening_port; } const std::string& get_listening_ip ( ) const { return listening_ip; } private: // data members int listening_socket; const int listening_port; const std::string listening_ip; const bool inaddr_any; listener( int sock, int port, const std::string& ip ); /*! requires - sock is a socket handle - sock is listening on the port and ip(may be "") indicated in the above parameters ensures - *this is initialized correctly with the above parameters !*/ // restricted functions listener(); listener(listener&); // copy constructor listener& operator=(listener&); // assignement opertor }; // ---------------------------------------------------------------------------------------- int create_listener ( listener*& new_listener, unsigned short port, const std::string& ip = "" ); int create_connection ( connection*& new_connection, unsigned short foreign_port, const std::string& foreign_ip, unsigned short local_port = 0, const std::string& local_ip = "" ); int create_listener ( std::unique_ptr& new_listener, unsigned short port, const std::string& ip = "" ); int create_connection ( std::unique_ptr& 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_