diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti index f4044af2b25a724a8cf5d85e1e3ffe77e37ab797..f595645dcab6fb882b7c1b291c3bafcc7baa3879 100644 --- a/Socket/ClientSocketHandle.cti +++ b/Socket/ClientSocketHandle.cti @@ -37,11 +37,19 @@ ClientSocketHandle(ClientSocketHandle<OtherPolicy> other, : SocketHandle<Policy>(other,true) {} +template <class Policy> +prefix_ satcom::lib::ClientSocketHandle<Policy>::ClientSocketHandle(FileHandle other, + bool isChecked) + : SocketHandle<Policy>(other, isChecked) +{} + template <class Policy> prefix_ satcom::lib::ClientSocketHandle<Policy>:: -ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol) +ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol, int fd) : SocketHandle<Policy>(protocol) -{} +{ + this->body().fd(fd); +} template <class Policy> template <class OtherPolicy> diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh index ae0868ee0e3548ad545868aa58543cff0fe06b63..1482a472a70ff948aa9dc06c59a0dc7c3478c55d 100644 --- a/Socket/ClientSocketHandle.hh +++ b/Socket/ClientSocketHandle.hh @@ -121,11 +121,14 @@ namespace lib { ///@} protected: - explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol); + ClientSocketHandle(FileHandle other, bool isChecked); + explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol, + int fd = -1); private: unsigned available(); + friend class satcom::lib::ServerSocketHandle<Policy>; }; }} diff --git a/Socket/CommunicationPolicy.cc b/Socket/CommunicationPolicy.cc new file mode 100644 index 0000000000000000000000000000000000000000..66ef9ae625e7ffeff72aade115eb3f162f30b18d --- /dev/null +++ b/Socket/CommunicationPolicy.cc @@ -0,0 +1,57 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// Definition of non-inline non-template functions + +#include "CommunicationPolicy.hh" +//#include "CommunicationPolicy.ih" + +// Custom includes +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#include "Utils/Exception.hh" +#include "ServerSocketHandle.hh" + +//#include "CommunicationPolicy.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ int satcom::lib::ConnectedCommunicationPolicy::do_accept(FileHandle handle, + struct sockaddr * addr, + unsigned len) +{ + int rv = ::accept(handle.fd(),addr,&len); + if (rv < 0) + throw SystemException(errno); + return rv; +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "CommunicationPolicy.mpp" + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/CommunicationPolicy.cti b/Socket/CommunicationPolicy.cti new file mode 100644 index 0000000000000000000000000000000000000000..f3be50d1e338828d0e88a990c65b29f4da476fce --- /dev/null +++ b/Socket/CommunicationPolicy.cti @@ -0,0 +1,48 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// Definition of inline template functions + +//#include "CommunicationPolicy.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cti.p/////////////////////////////////////// + +template <class Policy> +prefix_ int satcom::lib::ConnectedCommunicationPolicy:: +accept(ServerSocketHandle<Policy> handle, + typename ServerSocketHandle<Policy>::Address & address, + typename IfAddressingPolicyIsNot<Policy,NoAddressingPolicy>::type *) +{ + return do_accept(handle,address.sockaddr_p(),address.sockaddr_len()); +} + +///////////////////////////////cti.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/CommunicationPolicy.hh b/Socket/CommunicationPolicy.hh index e32a97d0a09fda6edb988c94b4fba28c1c868985..f1d84e77bffedcc15f651e4cd23c3bc505f02bbb 100644 --- a/Socket/CommunicationPolicy.hh +++ b/Socket/CommunicationPolicy.hh @@ -24,15 +24,29 @@ #define HH_CommunicationPolicy_ 1 // Custom includes +#include "SocketPolicy.hh" +#include "AddressingPolicy.hh" +#include "FileHandle.hh" //#include "CommunicationPolicy.mpp" ///////////////////////////////hh.p//////////////////////////////////////// +struct sockaddr; + namespace satcom { namespace lib { + + template <class Policy> class ServerSocketHandle; struct ConnectedCommunicationPolicy : public CommunicationPolicyBase - {}; + { + template <class Policy> + static int accept(ServerSocketHandle<Policy> handle, + typename ServerSocketHandle<Policy>::Address & address, + typename IfAddressingPolicyIsNot<Policy,NoAddressingPolicy>::type * = 0); + private: + static int do_accept(FileHandle handle, struct sockaddr * addr, unsigned len); + }; struct UnconnectedCommunicationPolicy : public CommunicationPolicyBase {}; @@ -43,7 +57,7 @@ namespace lib { ///////////////////////////////hh.e//////////////////////////////////////// //#include "CommunicationPolicy.cci" //#include "CommunicationPolicy.ct" -//#include "CommunicationPolicy.cti" +#include "CommunicationPolicy.cti" #endif diff --git a/Socket/INetAddress.cc b/Socket/INetAddress.cc index b1bde50a41bd50c5f40a767faea2f858f6d705a7..dfb30340df8ba0dfcd027185bef2072e5b855b87 100644 --- a/Socket/INetAddress.cc +++ b/Socket/INetAddress.cc @@ -35,13 +35,30 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ satcom::lib::INet4Address::INet4Address() +prefix_ satcom::lib::INet4Address::INet4Address(std::string host, unsigned port) { clear(); + // TODO: gethostbyname einbauen + if (::inet_aton(host.c_str(), &addr.sin_addr) == 0) + throw InvalidINetAddressException(); + addr.sin_port = htons(port); +} + +prefix_ std::string satcom::lib::INet4Address::str() + const +{ + std::stringstream s; + s << host() << ':' << port(); + return s.str(); } -prefix_ satcom::lib::INet4Address const & -satcom::lib::INet4Address::operator=(std::string const & address) +prefix_ void satcom::lib::INet4Address::clear() +{ + ::memset(&addr,0,sizeof(addr)); + addr.sin_family = AF_INET; +} + +prefix_ void satcom::lib::INet4Address::assignString(std::string address) { clear(); // TODO: gethostbyname einbauen @@ -57,32 +74,6 @@ satcom::lib::INet4Address::operator=(std::string const & address) catch (boost::bad_lexical_cast const & ex) { throw InvalidINetAddressException(); } - return *this; -} - -prefix_ satcom::lib::INet4Address const & -satcom::lib::INet4Address::operator=(std::pair<std::string, unsigned> const & address) -{ - clear(); - // TODO: gethostbyname einbauen - if (::inet_aton(address.first.c_str(), &addr.sin_addr) == 0) - throw InvalidINetAddressException(); - addr.sin_port = htons(address.second); - return *this; -} - -prefix_ std::string satcom::lib::INet4Address::str() - const -{ - std::stringstream s; - s << host() << ':' << port(); - return s.str(); -} - -prefix_ void satcom::lib::INet4Address::clear() -{ - ::memset(&addr,0,sizeof(addr)); - addr.sin_family = AF_INET; } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/INetAddress.cci b/Socket/INetAddress.cci index 94bfc1964a61af1e83a10931fa1d8dc81c5aa21d..20d707ab62cd8a5d6337f1aea5051500d1ce0137 100644 --- a/Socket/INetAddress.cci +++ b/Socket/INetAddress.cci @@ -28,17 +28,23 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ satcom::lib::INet4Address::INet4Address(std::string address) +prefix_ satcom::lib::INet4Address::INet4Address() +{ + clear(); +} + +prefix_ satcom::lib::INet4Address::INet4Address(char const * address) { - *this = address; + assignString(address); } -prefix_ satcom::lib::INet4Address::INet4Address(std::string host, unsigned port) +prefix_ satcom::lib::INet4Address::INet4Address(std::string address) { - *this = std::make_pair(host,port); + assignString(address); } prefix_ bool satcom::lib::INet4Address::operator==(INet4Address const & other) + const { return addr.sin_port == other.addr.sin_port && addr.sin_addr.s_addr == other.addr.sin_addr.s_addr; diff --git a/Socket/INetAddress.hh b/Socket/INetAddress.hh index 37fa31901e59650172d5cc1e58cdc854105c36c6..f6a87ab2be70a1471febe093c44e40acd9c830f4 100644 --- a/Socket/INetAddress.hh +++ b/Socket/INetAddress.hh @@ -38,13 +38,11 @@ namespace lib { { public: INet4Address(); + INet4Address(char const * address); INet4Address(std::string address); INet4Address(std::string host, unsigned port); - INet4Address const & operator=(std::string const & address); - INet4Address const & operator=(std::pair<std::string, unsigned> const & address); - - bool operator==(INet4Address const & other); + bool operator==(INet4Address const & other) const; std::string str() const; std::string host() const; @@ -59,6 +57,8 @@ namespace lib { unsigned sockaddr_len() const; private: + void assignString(std::string addr); + struct ::sockaddr_in addr; }; diff --git a/Socket/INetAddress.test.cc b/Socket/INetAddress.test.cc index e9e8b84211a3b3da18d4ee89fca17690523b1249..bcfa6078d4f531668e24fdb162cc59b2ff4aa2c0 100644 --- a/Socket/INetAddress.test.cc +++ b/Socket/INetAddress.test.cc @@ -43,15 +43,15 @@ BOOST_AUTO_UNIT_TEST(inet4Address) INet4Address addr; addr = "127.0.0.1:12345"; - addr = std::make_pair("127.0.0.1",12345); } { INet4Address addr1("127.0.0.1:12345"); - INet4Address addr2("127.0.0.1",12345); + INet4Address addr2(std::string("127.0.0.1:12345")); + INet4Address addr3("127.0.0.1",12345); } - BOOST_CHECK( INet4Address("127.0.0.1:12345") == INet4Address("127.0.0.1",12345) ); + BOOST_CHECK_EQUAL( INet4Address("127.0.0.1:12345"), INet4Address("127.0.0.1",12345) ); BOOST_CHECK_THROW( INet4Address("127.0.0.1"), InvalidINetAddressException ); BOOST_CHECK_THROW( INet4Address("foo@bar:12345"), InvalidINetAddressException ); diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti index 11b4f14b350f06b8b4d62577acc0bfeb45ac3d4f..bd4041f4f23aba21e3dc4b043668be5221046b81 100644 --- a/Socket/ProtocolClientSocketHandle.cti +++ b/Socket/ProtocolClientSocketHandle.cti @@ -37,18 +37,14 @@ prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::ProtocolClientS this->protocol().init_client(); } +#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolClientSocketHandle.mpp", 2)) +#include BOOST_PP_ITERATE() + template <class SocketProtocol> -template <class A1> prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>:: -ProtocolClientSocketHandle(A1 const & a1) - : ClientSocketHandle<typename SocketProtocol::Policy>( - std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol())) -{ - this->protocol().init_client(a1); -} - -#define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Socket/ProtocolClientSocketHandle.mpp", 2)) -#include BOOST_PP_ITERATE() +ProtocolClientSocketHandle(FileHandle other, bool isChecked) + : ClientSocketHandle<typename Protocol::Policy>(other, true) +{} template <class SocketProtocol> prefix_ SocketProtocol const & diff --git a/Socket/ProtocolClientSocketHandle.hh b/Socket/ProtocolClientSocketHandle.hh index 04579b49f3a24558b67b1efa2300a31743d855f0..fb06a4aabe1d6583fc20d8023b04278b6b4cbb80 100644 --- a/Socket/ProtocolClientSocketHandle.hh +++ b/Socket/ProtocolClientSocketHandle.hh @@ -32,6 +32,8 @@ namespace satcom { namespace lib { + template <class Protocol> class ProtocolServerSocketHandle; + /** \brief */ template <class SocketProtocol> @@ -49,10 +51,8 @@ namespace lib { ///@{ ProtocolClientSocketHandle(); - template <class A1> - ProtocolClientSocketHandle(A1 const & a1); -# define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Socket/ProtocolClientSocketHandle.mpp", 1)) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolClientSocketHandle.mpp", 1)) # include BOOST_PP_ITERATE() ///@} @@ -61,9 +61,10 @@ namespace lib { Protocol const & protocol(); protected: + ProtocolClientSocketHandle(FileHandle other, bool isChecked); private: - + friend class ProtocolServerSocketHandle<Protocol>; }; }} diff --git a/Socket/ProtocolClientSocketHandle.mpp b/Socket/ProtocolClientSocketHandle.mpp index 14a0149c906bdc8d6bd3350da4ab2898647a25ef..28046823ec3f75254c8015123bad1037734c8c2f 100644 --- a/Socket/ProtocolClientSocketHandle.mpp +++ b/Socket/ProtocolClientSocketHandle.mpp @@ -21,7 +21,7 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if !BOOST_PP_IS_ITERATING -#ifndef MPP_ProtocolClientSocketHandle +#ifndef MPP_ProtocolClientSocketHandle_ // Custom includes #include <boost/preprocessor/iteration/iterate.hpp> @@ -31,11 +31,11 @@ //////////////////////////////mpp.p//////////////////////////////////////// // Local Macros -#define mppArg(z,n,data) BOOST_PP_CAT(A,n) const & BOOST_PP_CAT(a,n) +#define mpp_PCSH_Arg(z,n,data) BOOST_PP_CAT(A,n) const & BOOST_PP_CAT(a,n) -#define mppTemplateParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A ) -#define mppMethodParameters() BOOST_PP_ENUM(BOOST_PP_ITERATION(), mppArg, ) -#define mppCallParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a ) +#define mpp_PCSH_TemplateParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A ) +#define mpp_PCSH_MethodParameters() BOOST_PP_ENUM(BOOST_PP_ITERATION(), mpp_PCSH_Arg, ) +#define mpp_PCSH_CallParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a ) ////// #endif @@ -48,8 +48,8 @@ // satcom::lib::ProtocolClientSocketHandle<SocketProtocol>:: // ProtocolClientSocketHandle (constructor) declaration -template < mppTemplateParameters() > -ProtocolClientSocketHandle( mppMethodParameters() ); +template < mpp_PCSH_TemplateParameters() > +ProtocolClientSocketHandle( mpp_PCSH_MethodParameters() ); ////// #elif BOOST_PP_ITERATION_FLAGS()==2 @@ -58,31 +58,31 @@ ProtocolClientSocketHandle( mppMethodParameters() ); // ProtocolClientSocketHandle (constructor) implementation template <class SocketProtocol> -template < mppTemplateParameters() > +template < mpp_PCSH_TemplateParameters() > prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol>:: -ProtocolClientSocketHandle( mppMethodParameters() ) +ProtocolClientSocketHandle( mpp_PCSH_MethodParameters() ) : ClientSocketHandle<typename SocketProtocol::Policy>( std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol())) { - this->protocol().init_client( mppCallParameters() ); + this->protocol().init_client( mpp_PCSH_CallParameters() ); } ////// #endif #endif #if !BOOST_PP_IS_ITERATING -#ifdef MPP_ProtocolClientSocketHandle_ +#ifdef MPP_PCSH__ProtocolClientSocketHandle_ /////////////////////////////////////////////////////////////////////////// // Undefine local Macros -#undef mppArg -#undef mppTemplateParameters -#undef mppMethodParameters -#undef mppCallParameters +#undef mpp_PCSH_Arg +#undef mpp_PCSH_TemplateParameters +#undef mpp_PCSH_MethodParameters +#undef mpp_PCSH_CallParameters -//////////////////////////////mpp.e//////////////////////////////////////// +//////////////////////////////mpp_PCSH_.e//////////////////////////////////////// #else -#define MPP_ProtocolClientSocketHandle_ 1 +#define MPP_PCSH__ProtocolClientSocketHandle_ 1 #endif #endif diff --git a/Socket/ProtocolClientSocketHandle.test.cc b/Socket/ProtocolClientSocketHandle.test.cc index 33273ba8da1fb1c7343419d2369a8e75339d6bef..7c73b90460aa173f1de8a8aca79d8398d477a3ae 100644 --- a/Socket/ProtocolClientSocketHandle.test.cc +++ b/Socket/ProtocolClientSocketHandle.test.cc @@ -47,10 +47,14 @@ BOOST_AUTO_UNIT_TEST(protocolClientSocketHandle) { typedef satcom::lib::ProtocolClientSocketHandle<MyProtocol> MySocketHandle; - MySocketHandle h; - h.protocol(); + { + MySocketHandle h; + h.protocol(); + } - MySocketHandle hh("foo.bar.c",1234); + { + MySocketHandle hh("foo.bar.c",1234); + } } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti index 16b72adbf54d70171d5c18c22274bac1ad0d6fb9..01087c5b6b9c12efe41191de05108c5d9312810c 100644 --- a/Socket/ProtocolServerSocketHandle.cti +++ b/Socket/ProtocolServerSocketHandle.cti @@ -25,6 +25,7 @@ //#include "ProtocolServerSocketHandle.ih" // Custom includes +#include "ProtocolClientSocketHandle.hh" #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// @@ -35,6 +36,9 @@ prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::ProtocolServerS std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol())) {} +#define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolServerSocketHandle.mpp", 2)) +#include BOOST_PP_ITERATE() + template <class SocketProtocol> prefix_ SocketProtocol const & satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::protocol() @@ -43,6 +47,13 @@ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::protocol() return static_cast<SocketProtocol const &>(this->body().protocol()); } +template <class SocketProtocol> +prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol> +satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::accept() +{ + return ProtocolClientSocketHandle<SocketProtocol>( + FileHandle(this->ServerSocketHandle<typename SocketProtocol::Policy>::accept()),true); +} ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/ProtocolServerSocketHandle.hh b/Socket/ProtocolServerSocketHandle.hh index 4d468b72c0cb5e91bbfbb5a6310a5a2ec0735ed4..3638199c76ccb149b630a63e691058a0acae6c0b 100644 --- a/Socket/ProtocolServerSocketHandle.hh +++ b/Socket/ProtocolServerSocketHandle.hh @@ -26,11 +26,13 @@ // Custom includes #include "ServerSocketHandle.hh" -//#include "ProtocolServerSocketHandle.mpp" +#include "ProtocolServerSocketHandle.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace satcom { namespace lib { + + template <class Protocol> class ProtocolClientSocketHandle; /** \brief */ @@ -48,15 +50,18 @@ namespace lib { ///\name Structors and default members ///@{ - // TODO: Non-default constructors (via argument forwarding - // to the SocketProtocol::init(...) methods ProtocolServerSocketHandle(); +# define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Socket/ProtocolServerSocketHandle.mpp", 1)) +# include BOOST_PP_ITERATE() + ///@} /////////////////////////////////////////////////////////////////////////// Protocol const & protocol(); + ProtocolClientSocketHandle<SocketProtocol> accept(); + protected: private: diff --git a/Socket/ProtocolServerSocketHandle.mpp b/Socket/ProtocolServerSocketHandle.mpp new file mode 100644 index 0000000000000000000000000000000000000000..029a99505ce18275fc9789251c6afefd7006bb1c --- /dev/null +++ b/Socket/ProtocolServerSocketHandle.mpp @@ -0,0 +1,93 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#if !BOOST_PP_IS_ITERATING +#ifndef MPP_PSSH__ProtocolServerSocketHandle_ + +// Custom includes +#include <boost/preprocessor/iteration/iterate.hpp> +#include <boost/preprocessor/enum.hpp> +#include <boost/preprocessor/cat.hpp> + +//////////////////////////////mpp_PSSH_.p//////////////////////////////////////// +// Local Macros + +#define mpp_PSSH_Arg(z,n,data) BOOST_PP_CAT(A,n) const & BOOST_PP_CAT(a,n) + +#define mpp_PSSH_TemplateParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A ) +#define mpp_PSSH_MethodParameters() BOOST_PP_ENUM(BOOST_PP_ITERATION(), mpp_PSSH_Arg, ) +#define mpp_PSSH_CallParameters() BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a ) + +////// +#endif +#else +/////////////////////////////////////////////////////////////////////////// + +////// +#if BOOST_PP_ITERATION_FLAGS()==1 +/////////////////////////////////////////////////////////////////////////// +// satcom::lib::ProtocolServerSocketHandle<SocketProtocol>:: +// ProtocolServerSocketHandle (constructor) declaration + +template < mpp_PSSH_TemplateParameters() > +ProtocolServerSocketHandle( mpp_PSSH_MethodParameters() ); + +////// +#elif BOOST_PP_ITERATION_FLAGS()==2 +/////////////////////////////////////////////////////////////////////////// +// satcom::lib::ProtocolServerSocketHandle<SocketProtocol>:: +// ProtocolServerSocketHandle (constructor) implementation + +template <class SocketProtocol> +template < mpp_PSSH_TemplateParameters() > +prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>:: +ProtocolServerSocketHandle( mpp_PSSH_MethodParameters() ) + : ServerSocketHandle<typename SocketProtocol::Policy>( + std::auto_ptr<satcom::lib::SocketProtocol>(new SocketProtocol())) +{ + this->protocol().init_server( mpp_PSSH_CallParameters() ); +} + +////// +#endif +#endif +#if !BOOST_PP_IS_ITERATING +#ifdef MPP_PSSH__ProtocolServerSocketHandle_ +/////////////////////////////////////////////////////////////////////////// +// Undefine local Macros + +#undef mpp_PSSH_Arg +#undef mpp_PSSH_TemplateParameters +#undef mpp_PSSH_MethodParameters +#undef mpp_PSSH_CallParameters + +//////////////////////////////mpp_PSSH_.e//////////////////////////////////////// +#else +#define MPP_PSSH__ProtocolServerSocketHandle_ 1 +#endif +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/ProtocolServerSocketHandle.test.cc b/Socket/ProtocolServerSocketHandle.test.cc index 1cd392008a34209ec47027478d023bbf7bd6bea6..98408955bb3c8de4be57ecf24460eae20642189d 100644 --- a/Socket/ProtocolServerSocketHandle.test.cc +++ b/Socket/ProtocolServerSocketHandle.test.cc @@ -27,7 +27,7 @@ // Custom includes #include "ProtocolServerSocketHandle.hh" -#include "ServerSocketHandle.test.hh" +#include "SocketProtocol.test.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> @@ -35,13 +35,29 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +namespace { + + struct MyProtocol : public satcom::lib::test::SomeProtocol + { + using satcom::lib::test::SomeProtocol::init_server; + void init_server(char const *,unsigned) const {} + }; +} + BOOST_AUTO_UNIT_TEST(protocolServerSocketHandle) { - typedef satcom::lib::ProtocolServerSocketHandle< - satcom::lib::test::SomeConnectedProtocol> MySocketHandle; + typedef satcom::lib::ProtocolServerSocketHandle<MyProtocol> MySocketHandle; + + { + MySocketHandle h; + + MySocketHandle::ClientSocketHandle client = h.accept(); + BOOST_CHECK_EQUAL( client.fd(), -1 ); + } - MySocketHandle h; - h.protocol(); + { + MySocketHandle h("foo.bar.c",1234); + } } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti index 59e8f022566d2b09aa8e0b40bffb991aec65d7da..b4cdcd84c60a6997b167fb381610a6328712b200 100644 --- a/Socket/ServerSocketHandle.cti +++ b/Socket/ServerSocketHandle.cti @@ -80,7 +80,27 @@ template <class Policy> prefix_ typename satcom::lib::ServerSocketHandle<Policy>::ClientSocketHandle satcom::lib::ServerSocketHandle<Policy>::accept() { - return Policy::CommunicationPolicy::accept(*this); + Address address; + return acceptfrom(address); +} + +template <class Policy> +prefix_ std::pair<typename satcom::lib::ServerSocketHandle<Policy>::ClientSocketHandle, + typename satcom::lib::ServerSocketHandle<Policy>::Address> +satcom::lib::ServerSocketHandle<Policy>::acceptfrom() +{ + + Address address; + ClientSocketHandle handle = accept(address); + return std::make_pair(handle,address); +} + +template <class Policy> +prefix_ typename satcom::lib::ServerSocketHandle<Policy>::ClientSocketHandle +satcom::lib::ServerSocketHandle<Policy>::acceptfrom(Address & addr) +{ + return ClientSocketHandle(this->protocol().clone(), + Policy::CommunicationPolicy::accept(*this,addr)); } ///////////////////////////////cti.e/////////////////////////////////////// diff --git a/Socket/ServerSocketHandle.hh b/Socket/ServerSocketHandle.hh index 95338f154809173ff17abf6851571574570d01e4..2f9b944d0288394cfe8849bc953dce0088c21985 100644 --- a/Socket/ServerSocketHandle.hh +++ b/Socket/ServerSocketHandle.hh @@ -44,12 +44,6 @@ namespace lib { class ServerSocketHandle : public SocketHandle<Policy> { - // FIXME: Are theese necessary ... hmm ... - BOOST_STATIC_ASSERT((boost::is_convertible< typename Policy::CommunicationPolicy *, - ConnectedCommunicationPolicy *>::value )); - BOOST_STATIC_ASSERT(!(boost::is_convertible< typename Policy::AddressingPolicy *, - NoAddressingPolicy *>::value )); - public: /////////////////////////////////////////////////////////////////////////// // Types @@ -88,8 +82,12 @@ namespace lib { Address local (); void local (Address & addr); - ClientSocketHandle + ClientSocketHandle accept (); + std::pair<ClientSocketHandle, Address> + acceptfrom (); + ClientSocketHandle + acceptfrom (Address & addr); ///@} @@ -97,7 +95,7 @@ namespace lib { explicit ServerSocketHandle(std::auto_ptr<SocketProtocol> protocol); private: - + }; }} diff --git a/Socket/ServerSocketHandle.test.cc b/Socket/ServerSocketHandle.test.cc index 121faf872109ba0d5ef304d5aa77f4752984d2a5..73909ac9c642667517926fc9b7d8cd9f819bba32 100644 --- a/Socket/ServerSocketHandle.test.cc +++ b/Socket/ServerSocketHandle.test.cc @@ -27,8 +27,8 @@ // Custom includes #include "ServerSocketHandle.hh" -#include "ServerSocketHandle.test.hh" #include "ClientSocketHandle.hh" +#include "SocketProtocol.test.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> @@ -41,12 +41,12 @@ namespace { namespace sl = satcom::lib; class MySocketHandle - : public sl::ServerSocketHandle<sl::test::SomeConnectedProtocol::Policy> + : public sl::ServerSocketHandle<sl::test::SomeProtocol::Policy> { public: MySocketHandle() - : sl::ServerSocketHandle<sl::test::SomeConnectedProtocol::Policy>( - std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeConnectedProtocol())) + : sl::ServerSocketHandle<sl::test::SomeProtocol::Policy>( + std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeProtocol())) {} }; } @@ -66,7 +66,12 @@ BOOST_AUTO_UNIT_TEST(serverSocketHandle) BOOST_CHECK_NO_THROW( myh.bind(0) ); BOOST_CHECK_EQUAL( myh.local(), 2u ); - // BOOST_CHECK_NO_THROW( myh.accept() ); + + { + MySocketHandle::ClientSocketHandle client = myh.accept(); + BOOST_CHECK_EQUAL( client.fd(), -1 ); + } + } diff --git a/Socket/ServerSocketHandle.test.hh b/Socket/ServerSocketHandle.test.hh deleted file mode 100644 index 96a64432a4fc0e49904deeb51a2b40097143ba74..0000000000000000000000000000000000000000 --- a/Socket/ServerSocketHandle.test.hh +++ /dev/null @@ -1,71 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund <stefan.bund@fokus.fraunhofer.de> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HH_ServerSocketHandle_test_ -#define HH_ServerSocketHandle_test_ 1 - -// Custom includes -#include "SocketPolicy.test.hh" -#include "SocketProtocol.hh" - -//#include "ServerSocketHandle.test.mpp" -///////////////////////////////hh.p//////////////////////////////////////// - -namespace satcom { -namespace lib { -namespace test { - - typedef satcom::lib::MakeSocketPolicy< - SomeAddressingPolicy, - SomeFramingPolicy, - ConnectedCommunicationPolicy, - SomeReadPolicy, - SomeWritePolicy, - SomeBufferingPolicy - >::policy SomeConnectedPolicy; - - class SomeConnectedProtocol - : public ConcreteSocketProtocol<SomeConnectedPolicy> - { - ~SomeConnectedProtocol() {} - - void init_client() const {} - void init_server() const {} - - unsigned available() const { return Policy::ReadPolicy::TEST_SIZE; } - bool eof() const { return false; } - }; - -}}} - -///////////////////////////////hh.e//////////////////////////////////////// -//#include "ServerSocketHandle.test.cci" -//#include "ServerSocketHandle.test.ct" -//#include "ServerSocketHandle.test.cti" -//#include "ServerSocketHandle.test.mpp" -#endif - - -// Local Variables: -// mode: c++ -// c-file-style: "satcom" -// End: diff --git a/Socket/SocketHandle.cci b/Socket/SocketHandle.cci index aa5a484922d284c51ca30db0083deadf309d8ecd..db18a754b0d0b37c33f5ba411ac10a08e606ba38 100644 --- a/Socket/SocketHandle.cci +++ b/Socket/SocketHandle.cci @@ -33,6 +33,14 @@ prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol) : protocol_(protocol) { + BOOST_ASSERT( ! protocol_->body_ ); + protocol_->body_ = this; +} + +prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol, int fd) + : FileBody(fd), protocol_(protocol) +{ + BOOST_ASSERT( ! protocol_->body_ ); protocol_->body_ = this; } diff --git a/Socket/SocketHandle.ih b/Socket/SocketHandle.ih index c66da91b7596b893d96c9d45ca16f7b615ab4b0a..103897bb781a3b9eee2dffc119c834b634dd2d4b 100644 --- a/Socket/SocketHandle.ih +++ b/Socket/SocketHandle.ih @@ -47,7 +47,8 @@ namespace lib { ///\name Structors and default members ///@{ - SocketBody(std::auto_ptr<SocketProtocol> protocol); + explicit SocketBody(std::auto_ptr<SocketProtocol> protocol); + SocketBody(std::auto_ptr<SocketProtocol> protocol, int fd); // no copy // no conversion constructors diff --git a/Socket/SocketPolicy.hh b/Socket/SocketPolicy.hh index 41aa09415b482c0e6b5dddbb6dfd889cc494b1a9..9200c8ea885fb6d73193c00a889fe9025a066ae0 100644 --- a/Socket/SocketPolicy.hh +++ b/Socket/SocketPolicy.hh @@ -101,28 +101,52 @@ namespace lib { struct SocketPolicyIsBaseOf; // the rest is implementation detail ... + template <class Policy, class Trait> + struct AddressingPolicyIs; template <class Policy, class Trait> struct IfAddressingPolicyIs; + template <class Policy, class Trait> + struct IfAddressingPolicyIsNot; // the rest is implementation detail ... + template <class Policy, class Trait> + struct FramingPolicyIs; template <class Policy, class Trait> struct IfFramingPolicyIs; + template <class Policy, class Trait> + struct IfFramingPolicyIsNot; // the rest is implementation detail ... + template <class Policy, class Trait> + struct CommunicationPolicyIs; template <class Policy, class Trait> struct IfCommunicationPolicyIs; + template <class Policy, class Trait> + struct IfCommunicationPolicyIsNot; // the rest is implementation detail ... + template <class Policy, class Trait> + struct ReadPolicyIs; template <class Policy, class Trait> struct IfReadPolicyIs; + template <class Policy, class Trait> + struct IfReadPolicyIsNot; // the rest is implementation detail ... + template <class Policy, class Trait> + struct WritePolicyIs; template <class Policy, class Trait> struct IfWritePolicyIs; + template <class Policy, class Trait> + struct IfWritePolicyIsNot; // the rest is implementation detail ... + template <class Policy, class Trait> + struct BufferingPolicyIs; template <class Policy, class Trait> struct IfBufferingPolicyIs; + template <class Policy, class Trait> + struct IfBufferingPolicyIsNot; // the rest is implementation detail ... }} diff --git a/Socket/SocketPolicy.ih b/Socket/SocketPolicy.ih index 6c666c08da7c41178b84490065a1fc3dea2d6260..d88a0e3e1153fb9de7b712ae0de28cda181f5fb4 100644 --- a/Socket/SocketPolicy.ih +++ b/Socket/SocketPolicy.ih @@ -28,6 +28,7 @@ #include <boost/mpl/fold.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/and.hpp> +#include <boost/utility.hpp> // for enable_if ///////////////////////////////ih.p//////////////////////////////////////// @@ -200,34 +201,94 @@ namespace lib { {}; template <class Policy, class Trait> - struct IfAddressingPolicyIs + struct AddressingPolicyIs : public boost::is_convertible< typename Policy::AddressingPolicy*, Trait* > {}; template <class Policy, class Trait> - struct IfFramingPolicyIs + struct IfAddressingPolicyIs + : public boost::enable_if< AddressingPolicyIs<Policy,Trait> > + {}; + + template <class Policy, class Trait> + struct IfAddressingPolicyIsNot + : public boost::enable_if_c< ! AddressingPolicyIs<Policy,Trait>::value > + {}; + + template <class Policy, class Trait> + struct FramingPolicyIs : public boost::is_convertible< typename Policy::FramingPolicy*, Trait* > {}; template <class Policy, class Trait> - struct IfCommunicationPolicyIs + struct IfFramingPolicyIs + : public boost::enable_if< FramingPolicyIs<Policy,Trait> > + {}; + + template <class Policy, class Trait> + struct IfFramingPolicyIsNot + : public boost::enable_if_c< ! FramingPolicyIs<Policy,Trait>::value > + {}; + + template <class Policy, class Trait> + struct CommunicationPolicyIs : public boost::is_convertible< typename Policy::CommunicationPolicy*, Trait* > {}; template <class Policy, class Trait> - struct IfReadPolicyIs + struct IfCommunicationPolicyIs + : public boost::enable_if< CommunicationPolicyIs<Policy,Trait> > + {}; + + template <class Policy, class Trait> + struct IfCommunicationPolicyIsNot + : public boost::enable_if_c< ! CommunicationPolicyIs<Policy,Trait>::value > + {}; + + template <class Policy, class Trait> + struct ReadPolicyIs : public boost::is_convertible< typename Policy::ReadPolicy*, Trait* > {}; template <class Policy, class Trait> - struct IfWritePolicyIs + struct IfReadPolicyIs + : public boost::enable_if< ReadPolicyIs<Policy,Trait> > + {}; + + template <class Policy, class Trait> + struct IfReadPolicyIsNot + : public boost::enable_if_c< ! ReadPolicyIs<Policy,Trait>::value > + {}; + + template <class Policy, class Trait> + struct WritePolicyIs : public boost::is_convertible< typename Policy::WritePolicy*, Trait* > {}; template <class Policy, class Trait> - struct IfBufferingPolicyIs + struct IfWritePolicyIs + : public boost::enable_if< WritePolicyIs<Policy,Trait> > + {}; + + template <class Policy, class Trait> + struct IfWritePolicyIsNot + : public boost::enable_if_c< ! WritePolicyIs<Policy,Trait>::value > + {}; + + template <class Policy, class Trait> + struct BufferingPolicyIs : public boost::is_convertible< typename Policy::BufferingPolicy*, Trait* > {}; + + template <class Policy, class Trait> + struct IfBufferingPolicyIs + : public boost::enable_if< BufferingPolicyIs<Policy,Trait> > + {}; + + template <class Policy, class Trait> + struct IfBufferingPolicyIsNot + : public boost::enable_if_c< ! BufferingPolicyIs<Policy,Trait>::value > + {}; }} ///////////////////////////////ih.e//////////////////////////////////////// diff --git a/Socket/SocketPolicy.test.hh b/Socket/SocketPolicy.test.hh index 86201fb0f7acb794de77625c90d350d2fdd92825..cebba2d2c97a6772408ef963fab1f4774af9b4ae 100644 --- a/Socket/SocketPolicy.test.hh +++ b/Socket/SocketPolicy.test.hh @@ -52,7 +52,10 @@ namespace test { {}; struct SomeCommunicationPolicy : public satcom::lib::CommunicationPolicyBase - {}; + { + static int accept(FileHandle handle, unsigned & addr) + { addr = 3; return -1; } + }; struct SomeReadPolicy : public satcom::lib::ReadPolicyBase { diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index 7964a3f4613b263833da63c6f8adf5ee7ec40234..4d1a9d58fa8c0e2d651f4b70606a39eb264284a4 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -33,6 +33,7 @@ namespace satcom { namespace lib { class SocketBody; + class FileHandle; /** \brief */ @@ -62,6 +63,7 @@ namespace lib { /////////////////////////////////////////////////////////////////////////// // Virtual interface + virtual std::auto_ptr<SocketProtocol> clone() const = 0; virtual unsigned available() const = 0; virtual bool eof() const = 0; diff --git a/Socket/SocketProtocol.test.hh b/Socket/SocketProtocol.test.hh index d3c43da39bf5bc63ad66b3a78c9afe3f5b14edf7..047a6a9338d445f6ccb60cc770a1719a1a37b4f8 100644 --- a/Socket/SocketProtocol.test.hh +++ b/Socket/SocketProtocol.test.hh @@ -26,6 +26,7 @@ // Custom includes #include "SocketProtocol.hh" #include "SocketPolicy.test.hh" +#include "ProtocolClientSocketHandle.hh" //#include "SocketProtocol.test.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -43,14 +44,12 @@ namespace test { void init_client() const {} void init_server() const {} - unsigned available() const { - return Policy::ReadPolicy::TEST_SIZE; - } - - bool eof() const { - return false; - } - + std::auto_ptr<SocketProtocol> clone() const + { return std::auto_ptr<SocketProtocol>(new SomeProtocol()); } + unsigned available() const + { return Policy::ReadPolicy::TEST_SIZE; } + bool eof() const + { return false; } }; }}} diff --git a/Socket/TCPSocketHandle.cc b/Socket/TCPSocketHandle.cc index 1a97f8022dbd9eb9246beded3df097ee1339658e..af9fa9c82ebacae939453879db9720a9d0ebe1aa 100644 --- a/Socket/TCPSocketHandle.cc +++ b/Socket/TCPSocketHandle.cc @@ -36,6 +36,24 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +prefix_ bool satcom::lib::TCPv4SocketProtocol::reuseraddr() + const +{ + int value; + socklen_t len (sizeof(value)); + if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0) + throw SystemException(errno); + return value; +} + +prefix_ void satcom::lib::TCPv4SocketProtocol::reuseaddr(bool value) + const +{ + int ivalue (value); + if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0) + throw SystemException(errno); +} + prefix_ void satcom::lib::TCPv4SocketProtocol::init_client() const { @@ -46,45 +64,51 @@ prefix_ void satcom::lib::TCPv4SocketProtocol::init_client() } prefix_ void -satcom::lib::TCPv4SocketProtocol::init_client(INet4AddressingPolicy::Address const & address) +satcom::lib::TCPv4SocketProtocol::init_client(INet4Address const & address) const { init_client(); connect(address); } -prefix_ void satcom::lib::TCPv4SocketProtocol::init_client(std::string address) +prefix_ void satcom::lib::TCPv4SocketProtocol::init_server() const { - init_client(); - connect(address); + int sock = ::socket(PF_INET,SOCK_STREAM,0); + if (sock < 0) + throw SystemException(errno); + body().fd(sock); } -prefix_ void satcom::lib::TCPv4SocketProtocol::init_client(std::string host, unsigned port) +prefix_ void +satcom::lib::TCPv4SocketProtocol::init_server(INet4Address const & address) const { - init_client(); - connect(host,port); + init_server(); + bind(address); + reuseaddr(true); + if (::listen(body().fd(),1) < 0) + throw SystemException(errno); } -prefix_ void -satcom::lib::TCPv4SocketProtocol::connect(INet4AddressingPolicy::Address const & address) +prefix_ void satcom::lib::TCPv4SocketProtocol::connect(INet4Address const & address) const { if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0) throw SystemException(errno); } -prefix_ void satcom::lib::TCPv4SocketProtocol::connect(std::string address) +prefix_ void satcom::lib::TCPv4SocketProtocol::bind(INet4Address const & address) const { - connect(INet4AddressingPolicy::Address(address)); + if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0) + throw SystemException(errno); } -prefix_ void satcom::lib::TCPv4SocketProtocol::connect(std::string host, unsigned port) +prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProtocol::clone() const { - connect(INet4AddressingPolicy::Address(host,port)); + return std::auto_ptr<SocketProtocol>(new TCPv4SocketProtocol()); } prefix_ unsigned satcom::lib::TCPv4SocketProtocol::available() diff --git a/Socket/TCPSocketHandle.hh b/Socket/TCPSocketHandle.hh index 571888047e7dc337c03c6883f6d1c4fc03fa76b5..e540315a5ffcac6ce91053faee76e841bab18410 100644 --- a/Socket/TCPSocketHandle.hh +++ b/Socket/TCPSocketHandle.hh @@ -54,15 +54,21 @@ namespace lib { public TCPProtocol { public: + bool reuseraddr() const; + void reuseaddr(bool value) const; + + /////////////////////////////////////////////////////////////////////////// + // internal interface + void init_client() const; - void init_client(INet4AddressingPolicy::Address const & address) const; - void init_client(std::string address) const; - void init_client(std::string host, unsigned port) const; + void init_client(INet4Address const & address) const; + void init_server() const; + void init_server(INet4Address const & address) const; - void connect(INet4AddressingPolicy::Address const & address) const; - void connect(std::string address) const; - void connect(std::string host, unsigned port) const; + void connect(INet4Address const & address) const; + void bind(INet4Address const & address) const; + std::auto_ptr<SocketProtocol> clone() const; unsigned available() const; bool eof() const; }; diff --git a/Socket/TCPSocketHandle.test.cc b/Socket/TCPSocketHandle.test.cc index e096e3bde626466bad1184e02a29493bb69286dc..9465419e14c2ab7b37d2127327c90b5bbe592618 100644 --- a/Socket/TCPSocketHandle.test.cc +++ b/Socket/TCPSocketHandle.test.cc @@ -54,6 +54,38 @@ namespace { _exit(1); } + int server_pid = 0; + + void start(void (*fn)()) + { + server_pid = ::fork(); + if (server_pid < 0) BOOST_FAIL("fork()"); + if (server_pid == 0) { + (*fn)(); + _exit(0); + } + } + + void wait() + { + int status; + if (waitpid(server_pid,&status,0)<0) + BOOST_FAIL("waitpid()"); + BOOST_CHECK_EQUAL( status , 0 ); + } + + void stop() + { + kill(server_pid,9); + wait(); + } + +} + +/////////////////////////////////////////////////////////////////////////// + +namespace { + void server() { int serv = socket(PF_INET,SOCK_STREAM,0); @@ -70,8 +102,6 @@ namespace { int sock = accept(serv,0,0); if (sock < 0) fail("accept()"); - /////////////////////////////////////////////////////////////////////////// - char buffer[1024]; while (1) { int n = read(sock,buffer,1024); @@ -80,39 +110,11 @@ namespace { write(sock,buffer,n); } - /////////////////////////////////////////////////////////////////////////// - if (shutdown(sock, SHUT_RDWR) < 0) fail("shutdown()"); if (close(sock) < 0) fail("close()"); if (close(serv) < 0) fail("close()"); } - int server_pid = 0; - - void start_server() - { - server_pid = ::fork(); - if (server_pid < 0) BOOST_FAIL("fork()"); - if (server_pid == 0) { - server(); - _exit(0); - } - } - - void wait_server() - { - int status; - if (waitpid(server_pid,&status,0)<0) - BOOST_FAIL("waitpid()"); - BOOST_CHECK_EQUAL( status , 0 ); - } - - void stop_server() - { - kill(server_pid,9); - wait_server(); - } - } BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle) @@ -122,16 +124,15 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle) BOOST_CHECK_THROW( sock.connect(satcom::lib::INet4Address("127.0.0.1:12345")), satcom::lib::SystemException ); BOOST_CHECK_THROW( sock.protocol().connect("127.0.0.1:12345"), satcom::lib::SystemException ); - BOOST_CHECK_THROW( sock.protocol().connect("127.0.0.1",12345), satcom::lib::SystemException ); } { - start_server(); + start(server); satcom::lib::TCPv4ClientSocketHandle sock; - BOOST_CHECK_NO_THROW( sock.bind(satcom::lib::INet4Address("127.0.0.1:23456")) ); - BOOST_CHECK_NO_THROW( sock.connect(satcom::lib::INet4Address("127.0.0.1:12345")) ); - BOOST_CHECK( sock.peer() == satcom::lib::INet4Address("127.0.0.1:12345") ); - BOOST_CHECK( sock.local() == satcom::lib::INet4Address("127.0.0.1:23456") ); + BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") ); + BOOST_CHECK_NO_THROW( sock.connect("127.0.0.1:12345") ); + BOOST_CHECK( sock.peer() == "127.0.0.1:12345" ); + BOOST_CHECK( sock.local() == "127.0.0.1:23456" ); BOOST_CHECK( sock.blocking() ); BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) ); BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u ); @@ -142,12 +143,59 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle) BOOST_CHECK( !sock.eof() ); sock.write("QUIT"); sleep(1); - stop_server(); + stop(); + sleep(1); BOOST_CHECK_EQUAL( sock.read(), "" ); BOOST_CHECK( sock.eof() ); BOOST_CHECK( !sock ); } +} + +/////////////////////////////////////////////////////////////////////////// + +namespace { + void client() + { + int sock = socket(PF_INET,SOCK_STREAM,0); + if (sock<0) fail("socket()"); + struct sockaddr_in sin; + sin.sin_family = AF_INET; + sin.sin_port = htons(12346); + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0) + fail("connect()"); + + char buffer[1024]; + while (1) { + int n = read(sock,buffer,1024); + if (n == 4 && strncmp(buffer,"QUIT",4) == 0) + break; + write(sock,buffer,n); + } + + if (shutdown(sock, SHUT_RDWR) < 0) fail("shutdown()"); + if (close(sock) < 0) fail("close()"); + } + +} + +BOOST_AUTO_UNIT_TEST(tcpv4ServerSocketHandle) +{ + { + BOOST_CHECKPOINT("Opening server socket"); + satcom::lib::TCPv4ServerSocketHandle server ("127.0.0.1:12346"); + BOOST_CHECKPOINT("Starting client"); + start(client); + + BOOST_CHECKPOINT("Accepting connection"); + satcom::lib::TCPv4ClientSocketHandle client = server.accept(); + BOOST_CHECK_NO_THROW(client.write("QUIT")); + + BOOST_CHECKPOINT("Stopping client"); + sleep(1); + stop(); + } } ///////////////////////////////cc.e////////////////////////////////////////