diff --git a/Socket/BufferingPolicy.cc b/Socket/BufferingPolicy.cc new file mode 100644 index 0000000000000000000000000000000000000000..e1c31718310ee63260a1c9d94f44743538e54de9 --- /dev/null +++ b/Socket/BufferingPolicy.cc @@ -0,0 +1,81 @@ +// $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 "BufferingPolicy.hh" +//#include "BufferingPolicy.ih" + +// Custom includes +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#include "Utils/Exception.hh" + +//#include "BufferingPolicy.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ unsigned satcom::lib::SocketBufferingPolicy::rcvbuf(FileHandle handle) +{ + unsigned size; + socklen_t len (sizeof(size)); + if (::getsockopt(handle.fd(),SOL_SOCKET,SO_RCVBUF,&size,&len) < 0) + throw SystemException(errno); + // Linux doubles the bufer size on setting the RCVBUF to cater for internal + // headers. We fix this up here .. (see lkml FAQ) + return size/2; +} + +prefix_ void satcom::lib::SocketBufferingPolicy::rcvbuf(FileHandle handle, unsigned size) +{ + if (::setsockopt(handle.fd(),SOL_SOCKET,SO_RCVBUF,&size,sizeof(size)) < 0) + throw SystemException(errno); +} + +prefix_ unsigned satcom::lib::SocketBufferingPolicy::sndbuf(FileHandle handle) +{ + unsigned size; + socklen_t len (sizeof(size)); + if (::getsockopt(handle.fd(),SOL_SOCKET,SO_SNDBUF,&size,&len) < 0) + throw SystemException(errno); + // Linux doubles the bufer size on setting the SNDBUF to cater for internal + // headers. We fix this up here .. (see lkml FAQ) + return size/2; + +} + +prefix_ void satcom::lib::SocketBufferingPolicy::sndbuf(FileHandle handle, unsigned size) +{ + if (::setsockopt(handle.fd(),SOL_SOCKET,SO_SNDBUF,&size,sizeof(size)) < 0) + throw SystemException(errno); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "BufferingPolicy.mpp" + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/BufferingPolicy.hh b/Socket/BufferingPolicy.hh index a79b179ba93d64eb51b400f26a1022e515c8e76a..9dccd88ac8a3f57d74507b0fa83d3296fd24468a 100644 --- a/Socket/BufferingPolicy.hh +++ b/Socket/BufferingPolicy.hh @@ -24,6 +24,7 @@ #define HH_BufferingPolicy_ 1 // Custom includes +#include "FileHandle.hh" #include "SocketPolicy.hh" //#include "BufferingPolicy.mpp" @@ -32,8 +33,15 @@ namespace satcom { namespace lib { + // TODO: Should this be dependent on Read / WritePolicy ? struct SocketBufferingPolicy : public BufferingPolicyBase - {}; + { + static unsigned rcvbuf(FileHandle handle); + static void rcvbuf(FileHandle handle, unsigned size); + + static unsigned sndbuf(FileHandle handle); + static void sndbuf(FileHandle handle, unsigned size); + }; }} diff --git a/Socket/ClientSocketHandle.ct b/Socket/ClientSocketHandle.ct index 0e33be03d7dddc008fc8fcff0bb0afebaecc6ed9..267913db89044be40442b76fb04b5b97c8be0184 100644 --- a/Socket/ClientSocketHandle.ct +++ b/Socket/ClientSocketHandle.ct @@ -25,7 +25,6 @@ //#include "ClientSocketHandle.ih" // Custom includes -#include <fcntl.h> #define prefix_ ///////////////////////////////ct.p//////////////////////////////////////// @@ -42,7 +41,6 @@ template <class Policy> prefix_ void satcom::lib::ClientSocketHandle<Policy>::read(std::string & buffer) { unsigned nread = available(); - // TODO: handle case where nread == 0 and socket is blocking // FIXME: This is not necessary correct and more or less a hack ... buffer.assign(nread,0); unsigned rv = this->read(const_cast<char *>(buffer.data()),nread); @@ -65,7 +63,6 @@ prefix_ void satcom::lib::ClientSocketHandle<Policy>:: readfrom(std::string & buffer, typename Policy::AddressingPolicy::Address & from) { unsigned nread = available(); - // TODO: handle case where nread == 0 and socket is blocking // FIXME: This is not necessary correct and more or less a hack ... buffer.assign(nread,0); unsigned rv = this->readfrom(const_cast<char *>(buffer.data()), nread, from); diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti index c2b2c8f8911c4354e9219f3e0d2132314bf842a3..f4044af2b25a724a8cf5d85e1e3ffe77e37ab797 100644 --- a/Socket/ClientSocketHandle.cti +++ b/Socket/ClientSocketHandle.cti @@ -148,6 +148,33 @@ bind(typename boost::call_traits<typename Policy::AddressingPolicy::Address>::pa Policy::AddressingPolicy::bind(*this,addr); } +/////////////////////////////////////////////////////////////////////////// +// Buffering + +template <class Policy> +prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::rcvbuf() +{ + return Policy::BufferingPolicy::rcvbuf(*this); +} + +template <class Policy> +prefix_ void satcom::lib::ClientSocketHandle<Policy>::rcvbuf(unsigned size) +{ + Policy::BufferingPolicy::rcvbuf(*this,size); +} + +template <class Policy> +prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::sndbuf() +{ + return Policy::BufferingPolicy::sndbuf(*this); +} + +template <class Policy> +prefix_ void satcom::lib::ClientSocketHandle<Policy>::sndbuf(unsigned size) +{ + Policy::BufferingPolicy::sndbuf(*this,size); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh index a623a5964a104eaf62f2b52666398df551d2cf0a..b7d56056b22111472e35873a553690d20cea78cd 100644 --- a/Socket/ClientSocketHandle.hh +++ b/Socket/ClientSocketHandle.hh @@ -99,14 +99,22 @@ namespace lib { void connect (AddressParam addr); void bind (AddressParam addr); - typename Policy::AddressingPolicy::Address - peer (); + Address peer (); void peer (Address & addr); + Address local (); + void local (Address & addr); - typename Policy::AddressingPolicy::Address - local (); - void local (Address & addr); + ///@} + /////////////////////////////////////////////////////////////////////////// + ///\name Buffering + ///@{ + + unsigned rcvbuf (); + void rcvbuf (unsigned size); + unsigned sndbuf (); + void sndbuf (unsigned size); + ///@} protected: diff --git a/Socket/ClientSocketHandle.test.cc b/Socket/ClientSocketHandle.test.cc index a31119a3a15b0c01464afb39d520661e98196fac..389f30ec85d33869cec4e925eec33dad22dcd290 100644 --- a/Socket/ClientSocketHandle.test.cc +++ b/Socket/ClientSocketHandle.test.cc @@ -107,6 +107,11 @@ BOOST_AUTO_UNIT_TEST(clientSocketHandle) BOOST_CHECK_NO_THROW( myh.bind(0) ); BOOST_CHECK_EQUAL( myh.peer(), 1u ); BOOST_CHECK_EQUAL( myh.local(), 2u ); + + BOOST_CHECK_EQUAL( myh.rcvbuf(), 0u ); + BOOST_CHECK_NO_THROW( myh.rcvbuf(1) ); + BOOST_CHECK_EQUAL( myh.sndbuf(), 0u ); + BOOST_CHECK_NO_THROW( myh.sndbuf(1) ); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/FileHandle.cc b/Socket/FileHandle.cc index d16dbb70fa98a327b0a1c1d2d8dea62d94145e50..257a9f1a41a9b1cf4d3afd3ddcc51bac12184010 100644 --- a/Socket/FileHandle.cc +++ b/Socket/FileHandle.cc @@ -26,6 +26,7 @@ //#include "FileHandle.ih" // Custom includes +#include <unistd.h> #include <sys/poll.h> #include <string.h> #include <errno.h> @@ -35,6 +36,29 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +prefix_ void satcom::lib::FileBody::v_close() +{ + if (::close(fd_) != 0) + throw SystemException(errno); +} + +prefix_ void satcom::lib::FileBody::v_terminate() +{ + ::close(fd_); +} + +prefix_ bool satcom::lib::FileBody::v_eof() + const +{ + return false; +} + +prefix_ bool satcom::lib::FileBody::v_valid() + const +{ + return true; +} + prefix_ bool satcom::lib::FileBody::blocking() const { @@ -43,16 +67,13 @@ prefix_ bool satcom::lib::FileBody::blocking() return ! (flags & O_NONBLOCK); } -prefix_ bool satcom::lib::FileBody::blocking(bool status) - const +prefix_ void satcom::lib::FileBody::blocking(bool status) { int flags = ::fcntl(fd(),F_GETFL); if (flags < 0) throw SystemException(errno); - bool old = flags & O_NONBLOCK; if (status) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (::fcntl(fd(), F_SETFL, flags) < 0) throw SystemException(errno); - return ! old; } prefix_ bool satcom::lib::FileBody::pollCheck(int fd, bool incoming, bool block) diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci index f63792c5abbb656e2f7ce6266d7fb037e0ef9da7..301990fd60cf51b178850de8b14b52b5e8f003f0 100644 --- a/Socket/FileHandle.cci +++ b/Socket/FileHandle.cci @@ -25,7 +25,6 @@ //#include "FileHandle.ih" // Custom includes -#include <unistd.h> #include <errno.h> #include "Utils/Exception.hh" @@ -50,51 +49,43 @@ prefix_ satcom::lib::FileBody::~FileBody() } } -prefix_ int satcom::lib::FileBody::fd() - const +prefix_ void satcom::lib::FileBody::close() { - return fd_; + if (!valid()) + throw SystemException(EBADF); + v_close(); + fd_ = -1; } -prefix_ int satcom::lib::FileBody::fd(int fd) +prefix_ void satcom::lib::FileBody::terminate() { - int oldFd (fd_); - fd_ = fd; - return oldFd; + if (valid()) { + v_terminate(); + fd_ = -1; + } } -prefix_ void satcom::lib::FileBody::close() +prefix_ int satcom::lib::FileBody::fd() + const { - if (::close(fd_) != 0) - throw SystemException(errno); - fd_ = -1; + return fd_; } -prefix_ void satcom::lib::FileBody::terminate() +prefix_ void satcom::lib::FileBody::fd(int fd) { - ::close(fd_); - fd_ = -1; + fd_ = fd; } -prefix_ void satcom::lib::FileBody::flush() -{} - prefix_ bool satcom::lib::FileBody::eof() const { - return false; + return v_eof(); } prefix_ bool satcom::lib::FileBody::valid() const { - return fd_ != -1; -} - -prefix_ bool satcom::lib::FileBody::ok() - const -{ - return valid() && !eof(); + return fd_!=-1 && v_valid(); } prefix_ bool satcom::lib::FileBody::readable() @@ -134,11 +125,6 @@ prefix_ void satcom::lib::FileHandle::terminate() body().terminate(); } -prefix_ void satcom::lib::FileHandle::flush() -{ - body().flush(); -} - prefix_ bool satcom::lib::FileHandle::readable() const { @@ -169,9 +155,9 @@ prefix_ bool satcom::lib::FileHandle::blocking() return body().blocking(); } -prefix_ bool satcom::lib::FileHandle::blocking(bool status) +prefix_ void satcom::lib::FileHandle::blocking(bool status) { - return body().blocking(status); + body().blocking(status); } prefix_ bool satcom::lib::FileHandle::eof() @@ -189,13 +175,13 @@ prefix_ bool satcom::lib::FileHandle::valid() prefix_ satcom::lib::FileHandle::operator bool () const { - return body().ok(); + return valid() && !eof(); } prefix_ bool satcom::lib::FileHandle::operator!() const { - return ! body().ok(); + return ! (valid() && !eof()); } prefix_ int satcom::lib::FileHandle::fd() @@ -219,9 +205,9 @@ prefix_ satcom::lib::FileBody const & satcom::lib::FileHandle::body() return *body_; } -prefix_ int satcom::lib::FileHandle::fd(int fd) +prefix_ void satcom::lib::FileHandle::fd(int fd) { - return body().fd(fd); + body().fd(fd); } ///////////////////////////////cci.e/////////////////////////////////////// diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh index 0162ec73e50f6b2dac23b195d279999b737530f0..9027c7c8773c010daa95efc075b92f3dfc01d1aa 100644 --- a/Socket/FileHandle.hh +++ b/Socket/FileHandle.hh @@ -25,8 +25,6 @@ // Custom includes #include <memory> // std::auto_ptr -#include <boost/intrusive_ptr.hpp> -#include "Utils/intrusive_refcount.hh" //#include "FileHandle.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -59,7 +57,6 @@ namespace lib { void close(); void terminate(); - void flush(); bool readable() const; void waitReadable() const; @@ -67,7 +64,7 @@ namespace lib { void waitWritable() const; bool blocking() const; - bool blocking(bool status); + void blocking(bool status); bool eof() const; bool valid() const; @@ -83,7 +80,7 @@ namespace lib { FileBody & body(); FileBody const & body() const; - int fd(int fd); + void fd(int fd); private: FileBody::ptr body_; diff --git a/Socket/FileHandle.ih b/Socket/FileHandle.ih index b6ce3f0fe95e86667cf9b96856e202e79385cdfe..8135db48689a6134e7e89975988f6826d2881b9a 100644 --- a/Socket/FileHandle.ih +++ b/Socket/FileHandle.ih @@ -24,6 +24,8 @@ #define IH_FileHandle_ 1 // Custom includes +#include <boost/intrusive_ptr.hpp> +#include "Utils/intrusive_refcount.hh" ///////////////////////////////ih.p//////////////////////////////////////// @@ -55,12 +57,10 @@ namespace lib { /////////////////////////////////////////////////////////////////////////// int fd() const; - int fd(int fd); + void fd(int fd); - // TODO: Move theese to i_* and make the public iface non-virtual - virtual void close(); - virtual void terminate(); - virtual void flush(); + void close(); + void terminate(); bool readable() const; void waitReadable() const; @@ -68,11 +68,20 @@ namespace lib { void waitWritable() const; bool blocking() const; - bool blocking(bool status) const; + void blocking(bool status); - virtual bool eof() const; - virtual bool valid() const; - bool ok() const; + bool eof() const; + bool valid() const; + + private: + /////////////////////////////////////////////////////////////////////////// + // Virtual interface for subclasses to override + + virtual void v_close(); + virtual void v_terminate(); + virtual bool v_eof() const; + virtual bool v_valid() const; + protected: diff --git a/Socket/INetAddress.cci b/Socket/INetAddress.cci index dde22885fe24980cb8a5e773ae7939dc1859dbab..94bfc1964a61af1e83a10931fa1d8dc81c5aa21d 100644 --- a/Socket/INetAddress.cci +++ b/Socket/INetAddress.cci @@ -24,7 +24,6 @@ // Custom includes #include <arpa/inet.h> -#include <netinet/in.h> #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// diff --git a/Socket/INetProtocol.cci b/Socket/INetProtocol.cc similarity index 87% rename from Socket/INetProtocol.cci rename to Socket/INetProtocol.cc index 5f2e1d350d1e2fda0e855f7f19b85e3576c854b3..efdf8a75a0cae04ead0ed56c62f285d6b531b51b 100644 --- a/Socket/INetProtocol.cci +++ b/Socket/INetProtocol.cc @@ -20,14 +20,18 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// Definition of inline non-template functions +// Definition of non-inline non-template functions + +#include "INetProtocol.hh" +//#include "INetProtocol.ih" // Custom includes #include <sys/socket.h> #include "Utils/Exception.hh" -#define prefix_ inline -///////////////////////////////cci.p/////////////////////////////////////// +//#include "INetProtocol.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// prefix_ void satcom::lib::INet4AddressingPolicy::local(FileHandle handle, Address & addr) { @@ -58,8 +62,9 @@ prefix_ void satcom::lib::INet4AddressingPolicy::do_connect(FileHandle handle, throw SystemException(errno); } -///////////////////////////////cci.e/////////////////////////////////////// +///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ +//#include "INetProtocol.mpp" // Local Variables: diff --git a/Socket/INetProtocol.hh b/Socket/INetProtocol.hh index 3f35fbba2a7ef8bfc9225cf4e1f2242c7aa205aa..24e520469daa0c2f774ee6e0881192238410828f 100644 --- a/Socket/INetProtocol.hh +++ b/Socket/INetProtocol.hh @@ -70,7 +70,7 @@ namespace lib { }} ///////////////////////////////hh.e//////////////////////////////////////// -#include "INetProtocol.cci" +//#include "INetProtocol.cci" //#include "INetProtocol.ct" #include "INetProtocol.cti" #endif diff --git a/Socket/ReadWritePolicy.cci b/Socket/ReadWritePolicy.cc similarity index 58% rename from Socket/ReadWritePolicy.cci rename to Socket/ReadWritePolicy.cc index 28a6f223a0f48208f92eb3e7c8cba8d8641324d5..e6dc8a0a3a67d37051f2c865bf05aecb6c05e1bb 100644 --- a/Socket/ReadWritePolicy.cci +++ b/Socket/ReadWritePolicy.cc @@ -20,14 +20,21 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// Definition of inline non-template functions +// Definition of non-inline non-template functions + +#include "ReadWritePolicy.hh" +//#include "ReadWritePolicy.ih" // Custom includes +#include <sys/types.h> +#include <sys/socket.h> #include <unistd.h> #include <errno.h> -#define prefix_ inline -///////////////////////////////cci.p/////////////////////////////////////// + +//#include "ReadWritePolicy.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// prefix_ unsigned satcom::lib::ReadablePolicy::read(FileHandle handle, char * buffer, unsigned size) @@ -38,6 +45,16 @@ prefix_ unsigned satcom::lib::ReadablePolicy::read(FileHandle handle, char * buf return rv; } +prefix_ unsigned satcom::lib::ReadablePolicy::do_readfrom(FileHandle handle, char * buffer, + unsigned size, + struct ::sockaddr * addr, socklen_t len) +{ + int rv = ::recvfrom(handle.fd(),buffer, size, 0, addr, &len); + if (rv < 0) + throw SystemException(errno); + return rv; +} + prefix_ unsigned satcom::lib::WriteablePolicy::do_write(FileHandle handle, char const * buffer, unsigned size) { @@ -47,8 +64,19 @@ prefix_ unsigned satcom::lib::WriteablePolicy::do_write(FileHandle handle, char return rv; } -///////////////////////////////cci.e/////////////////////////////////////// +prefix_ unsigned satcom::lib::WriteablePolicy::do_writeto(FileHandle handle, + char const * buffer, unsigned size, + struct sockaddr * addr, socklen_t len) +{ + int rv = ::sendto(handle.fd(), buffer, size, 0, addr, len); + if (rv < 0) + throw SystemException(errno); + return rv; +} + +///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ +//#include "ReadWritePolicy.mpp" // Local Variables: diff --git a/Socket/ReadWritePolicy.cti b/Socket/ReadWritePolicy.cti index 6a8901952312b4d347313c2de865b78ab96441c2..f4f7f84f20d0419e216e0d9c8f385674e514e249 100644 --- a/Socket/ReadWritePolicy.cti +++ b/Socket/ReadWritePolicy.cti @@ -25,8 +25,6 @@ //#include "ReadWritePolicy.ih" // Custom includes -#include <unistd.h> -#include <errno.h> #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// @@ -37,11 +35,7 @@ readfrom(ClientSocketHandle<Policy> handle, char * buffer, unsigned size, typename Policy::AddressingPolicy::Address & address, typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type *) { - int rv = ::recvfrom(handle.fd(),buffer, size, 0, - address.sockaddr_p(), address.sockaddr_len()); - if (rv < 0) - throw SystemException(errno); - return rv; + return do_rcvfrom(handle, buffer, size, address.sockaddr_p(), address.sockaddr_len()); } template <class Policy> @@ -59,11 +53,7 @@ writeto(ClientSocketHandle<Policy> handle, char const * buffer, unsigned size, typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type *) { - int rv = ::sendto(handle.fd(), buffer, size, 0, - addr.sockaddr_p(), addr.sockaddr_len()); - if (rv < 0) - throw SystemException(errno); - return rv; + return do_writeto(handle, buffer, size, addr.sockaddr_p(), addr.sockaddr_len()); } ///////////////////////////////cti.e/////////////////////////////////////// diff --git a/Socket/ReadWritePolicy.hh b/Socket/ReadWritePolicy.hh index 204db53c322b117c1fb3bfa158a5fb04d9d1e5a0..4f9198d82a263abeee9cbb82ecfc25c95fe213c1 100644 --- a/Socket/ReadWritePolicy.hh +++ b/Socket/ReadWritePolicy.hh @@ -34,6 +34,8 @@ // TODO: ReadWritePolicy.test.cc ... // TODO: EINTR, EAGAIN etc handling ... +struct sockaddr; + namespace satcom { namespace lib { @@ -44,6 +46,10 @@ namespace lib { static unsigned readfrom(ClientSocketHandle<Policy> handle, char * buffer, unsigned size, typename Policy::AddressingPolicy::Address & address, typename IfCommunicationPolicyIs<Policy,UnconnectedCommunicationPolicy>::type * = 0); + + private: + static unsigned do_readfrom(FileHandle handle, char * buffer, unsigned size, + struct ::sockaddr * addr, socklen_t len); }; struct NotReadablePolicy : public ReadPolicyBase @@ -62,6 +68,8 @@ namespace lib { private: static unsigned do_write(FileHandle handle, char const * buffer, unsigned size); + static unsigned do_writeto(FileHandle handle, char const * buffer, unsigned size, + struct sockaddr * addr, socklen_t len); }; struct NotWriteablePolicy : public WritePolicyBase @@ -71,7 +79,7 @@ namespace lib { ///////////////////////////////hh.e//////////////////////////////////////// -#include "ReadWritePolicy.cci" +//#include "ReadWritePolicy.cci" //#include "ReadWritePolicy.ct" #include "ReadWritePolicy.cti" #endif diff --git a/Socket/SocketHandle.cc b/Socket/SocketHandle.cc new file mode 100644 index 0000000000000000000000000000000000000000..bdea5f511b261277b4da66b464a6dc025d5c9749 --- /dev/null +++ b/Socket/SocketHandle.cc @@ -0,0 +1,71 @@ +// $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 "SocketHandle.hh" +#include "SocketHandle.ih" + +// Custom includes +#include <sys/socket.h> + +//#include "SocketHandle.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ void satcom::lib::SocketBody::v_close() +{ + if (::shutdown(fd(),SHUT_RDWR) < 0) + throw SystemException(errno); + if (::close(fd()) < 0) + throw SystemException(errno); +} + +prefix_ void satcom::lib::SocketBody::v_terminate() +{ + struct linger ling; + ling.l_onoff = 0; + ling.l_linger = 0; + + // We purposely IGNORE any errors: this method is used to try and + // terminate the connection ignoring any possible problems + + ::setsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)); + ::shutdown(fd(),SHUT_RDWR); + ::close(fd()); +} + +prefix_ bool satcom::lib::SocketBody::v_eof() + const +{ + return protocol().eof(); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "SocketHandle.mpp" + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/SocketHandle.cci b/Socket/SocketHandle.cci index 188279c38996556d5a6ede9550ebdc6275614006..aa5a484922d284c51ca30db0083deadf309d8ecd 100644 --- a/Socket/SocketHandle.cci +++ b/Socket/SocketHandle.cci @@ -25,6 +25,7 @@ #include "SocketHandle.ih" // Custom includes +#include "Utils/Exception.hh" #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// @@ -41,12 +42,6 @@ prefix_ satcom::lib::SocketProtocol const & satcom::lib::SocketBody::protocol() return *protocol_; } -prefix_ bool satcom::lib::SocketBody::eof() - const -{ - return protocol().eof(); -} - ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/SocketHandle.ih b/Socket/SocketHandle.ih index 58d7478b997430c6e64d03c412329d0d0ce849a0..c66da91b7596b893d96c9d45ca16f7b615ab4b0a 100644 --- a/Socket/SocketHandle.ih +++ b/Socket/SocketHandle.ih @@ -57,11 +57,11 @@ namespace lib { SocketProtocol const & protocol() const; - virtual bool eof() const; - - protected: - private: + virtual void v_close(); + virtual void v_terminate(); + virtual bool v_eof() const; + boost::scoped_ptr<SocketProtocol> protocol_; }; diff --git a/Socket/SocketPolicy.test.hh b/Socket/SocketPolicy.test.hh index 42fb5bf143756ea68ccee431e8439f19236a057f..86201fb0f7acb794de77625c90d350d2fdd92825 100644 --- a/Socket/SocketPolicy.test.hh +++ b/Socket/SocketPolicy.test.hh @@ -90,7 +90,17 @@ namespace test { }; struct SomeBufferingPolicy : public satcom::lib::BufferingPolicyBase - {}; + { + static unsigned rcvbuf(FileHandle handle) + { return 0; } + static unsigned rcvbuf(FileHandle handle, unsigned size) + { return 0; } + + static unsigned sndbuf(FileHandle handle) + { return 0; } + static unsigned sndbuf(FileHandle handle, unsigned size) + { return 0; } + }; typedef satcom::lib::MakeSocketPolicy< SomeAddressingPolicy, diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index ce6f43e7d5235be83e97a1af39ea91bffd4b9e8b..7964a3f4613b263833da63c6f8adf5ee7ec40234 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -60,6 +60,7 @@ namespace lib { SocketBody & body() const; /////////////////////////////////////////////////////////////////////////// + // Virtual interface virtual unsigned available() const = 0; virtual bool eof() const = 0; diff --git a/Socket/SocketProtocol.test.hh b/Socket/SocketProtocol.test.hh index d839852ecbb5f768f5c4af75fb92cb292ca6748e..d3c43da39bf5bc63ad66b3a78c9afe3f5b14edf7 100644 --- a/Socket/SocketProtocol.test.hh +++ b/Socket/SocketProtocol.test.hh @@ -50,6 +50,7 @@ namespace test { bool eof() const { return false; } + }; }}} diff --git a/Socket/TCPSocketHandle.test.cc b/Socket/TCPSocketHandle.test.cc index 635f0e0f1739a4cd5e4a87fbd0914482ee4f45a9..e096e3bde626466bad1184e02a29493bb69286dc 100644 --- a/Socket/TCPSocketHandle.test.cc +++ b/Socket/TCPSocketHandle.test.cc @@ -133,6 +133,10 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle) 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( sock.blocking() ); + BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) ); + BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u ); + BOOST_CHECK_NO_THROW( sock.sndbuf(2048) ); + BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u ); BOOST_CHECK_NO_THROW( sock.write("TEST-WRITE") ); BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" ); BOOST_CHECK( !sock.eof() ); @@ -142,21 +146,6 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle) BOOST_CHECK_EQUAL( sock.read(), "" ); BOOST_CHECK( sock.eof() ); BOOST_CHECK( !sock ); - -// BOOST_CHECK_EQUAL( sock.write("x"), 1u ); -// BOOST_CHECK_EQUAL( sock.write("TEST-WRITE"), 10u ); -// int v = -1; -// ioctl(sock.fd(),TIOCOUTQ,&v,sizeof(v)); -// std::cerr << v << "\n"; -// sleep(10); -// ioctl(sock.fd(),TIOCOUTQ,&v,sizeof(v)); -// std::cerr << v << "\n"; -// BOOST_CHECK_EQUAL( sock.write("TEST-WRITE"), 10u ); -// ioctl(sock.fd(),TIOCOUTQ,&v,sizeof(v)); -// std::cerr << v << "\n"; -// sleep(10); -// ioctl(sock.fd(),TIOCOUTQ,&v,sizeof(v)); -// std::cerr << v << "\n"; } }