From 4cb8ac94940038fc7c083e217769553460de6ba6 Mon Sep 17 00:00:00 2001
From: sbund <sbund@wiback.org>
Date: Thu, 31 Aug 2006 08:59:32 +0000
Subject: [PATCH] server socket handle

---
 Socket/ClientSocketHandle.cti             |  12 ++-
 Socket/ClientSocketHandle.hh              |   5 +-
 Socket/CommunicationPolicy.cc             |  57 ++++++++++
 Socket/CommunicationPolicy.cti            |  48 +++++++++
 Socket/CommunicationPolicy.hh             |  18 +++-
 Socket/INetAddress.cc                     |  49 ++++-----
 Socket/INetAddress.cci                    |  14 ++-
 Socket/INetAddress.hh                     |   8 +-
 Socket/INetAddress.test.cc                |   6 +-
 Socket/ProtocolClientSocketHandle.cti     |  16 ++-
 Socket/ProtocolClientSocketHandle.hh      |   9 +-
 Socket/ProtocolClientSocketHandle.mpp     |  34 +++---
 Socket/ProtocolClientSocketHandle.test.cc |  10 +-
 Socket/ProtocolServerSocketHandle.cti     |  11 ++
 Socket/ProtocolServerSocketHandle.hh      |  11 +-
 Socket/ProtocolServerSocketHandle.mpp     |  93 +++++++++++++++++
 Socket/ProtocolServerSocketHandle.test.cc |  26 ++++-
 Socket/ServerSocketHandle.cti             |  22 +++-
 Socket/ServerSocketHandle.hh              |  14 ++-
 Socket/ServerSocketHandle.test.cc         |  15 ++-
 Socket/ServerSocketHandle.test.hh         |  71 -------------
 Socket/SocketHandle.cci                   |   8 ++
 Socket/SocketHandle.ih                    |   3 +-
 Socket/SocketPolicy.hh                    |  24 +++++
 Socket/SocketPolicy.ih                    |  73 +++++++++++--
 Socket/SocketPolicy.test.hh               |   5 +-
 Socket/SocketProtocol.hh                  |   2 +
 Socket/SocketProtocol.test.hh             |  15 ++-
 Socket/TCPSocketHandle.cc                 |  50 ++++++---
 Socket/TCPSocketHandle.hh                 |  18 ++--
 Socket/TCPSocketHandle.test.cc            | 122 +++++++++++++++-------
 31 files changed, 625 insertions(+), 244 deletions(-)
 create mode 100644 Socket/CommunicationPolicy.cc
 create mode 100644 Socket/CommunicationPolicy.cti
 create mode 100644 Socket/ProtocolServerSocketHandle.mpp
 delete mode 100644 Socket/ServerSocketHandle.test.hh

diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti
index f4044af2b..f595645dc 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 ae0868ee0..1482a472a 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 000000000..66ef9ae62
--- /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 000000000..f3be50d1e
--- /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 e32a97d0a..f1d84e77b 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 b1bde50a4..dfb30340d 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 94bfc1964..20d707ab6 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 37fa31901..f6a87ab2b 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 e9e8b8421..bcfa6078d 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 11b4f14b3..bd4041f4f 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 04579b49f..fb06a4aab 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 14a0149c9..28046823e 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 33273ba8d..7c73b9046 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 16b72adbf..01087c5b6 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 4d468b72c..3638199c7 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 000000000..029a99505
--- /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 1cd392008..98408955b 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 59e8f0225..b4cdcd84c 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 95338f154..2f9b944d0 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 121faf872..73909ac9c 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 96a64432a..000000000
--- 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 aa5a48492..db18a754b 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 c66da91b7..103897bb7 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 41aa09415..9200c8ea8 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 6c666c08d..d88a0e3e1 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 86201fb0f..cebba2d2c 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 7964a3f46..4d1a9d58f 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 d3c43da39..047a6a933 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 1a97f8022..af9fa9c82 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 571888047..e540315a5 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 e096e3bde..9465419e1 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////////////////////////////////////////
-- 
GitLab