X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fsocket.cpp;h=dd6c526e994fdeb9dd5fc12da0ce9c9822608793;hb=2aab4004e71a2e5c773289e0be5e58aec6a8d339;hp=fcd686f1f24d810fb1eef4a6bc8faf139c841288;hpb=3970ee9cf7978c462390d49e083deb740d71c6fe;p=libs%2Fnet.git diff --git a/source/socket.cpp b/source/socket.cpp index fcd686f..dd6c526 100644 --- a/source/socket.cpp +++ b/source/socket.cpp @@ -1,10 +1,3 @@ -/* $Id$ - -This file is part of libmspnet -Copyright © 2008 Mikkosoft Productions, Mikko Rasa -Distributed under the LGPL -*/ - #ifndef WIN32 #include #include @@ -43,6 +36,39 @@ WinSockHelper wsh; namespace Msp { namespace Net { +Socket::Socket(SocketHandle h, const SockAddr &paddr): + handle(h), + connected(true), + local_addr(0), + peer_addr(paddr.copy()) +{ + sockaddr_storage sa; + socklen_t size=sizeof(sockaddr_storage); + getsockname(handle, reinterpret_cast(&sa), &size); + local_addr=SockAddr::create(sa); + +#ifdef WIN32 + event=CreateEvent(0, false, false, 0); +#endif +} + +Socket::Socket(Family af, int type, int proto): + connected(false), + local_addr(0), + peer_addr(0) +{ + handle=socket(af, type, proto); + +#ifdef WIN32 + event=CreateEvent(0, false, false, 0); +#endif +} + +Socket::~Socket() +{ + close(); +} + void Socket::set_block(bool b) { mode=(mode&~IO::M_NONBLOCK); @@ -72,10 +98,10 @@ void Socket::bind(const SockAddr &addr) { check_state(false); - sockaddr sa; + sockaddr_storage sa; unsigned size=addr.fill_sockaddr(sa); - int err=::bind(handle, &sa, size); + int err=::bind(handle, reinterpret_cast(&sa), size); if(err==-1) throw SystemError("Unable to bind", errno); @@ -84,7 +110,7 @@ void Socket::bind(const SockAddr &addr) } /** -Closes the socket. Most operations on the socket will return an error after +Closes the socket. Most operations on the socket will throw an exception after this. */ void Socket::close() @@ -102,6 +128,7 @@ void Socket::close() ::close(handle); #endif handle=MSP_NET_INVALID_SOCKET_HANDLE; + connected=false; signal_closed.emit(); delete local_addr; @@ -110,6 +137,20 @@ void Socket::close() peer_addr=0; } +void Socket::set_timeout(const Time::TimeDelta &timeout) +{ +#ifndef WIN32 + timeval tv; + timeout.fill_timeval(tv); + set_option(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(timeval)); + set_option(SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(timeval)); +#else + DWORD msecs = static_cast(timeout/Time::msec); + set_option(SOL_SOCKET, SO_RCVTIMEO, &msecs, sizeof(DWORD)); + set_option(SOL_SOCKET, SO_SNDTIMEO, &msecs, sizeof(DWORD)); +#endif +} + const SockAddr &Socket::get_local_address() const { if(local_addr==0) @@ -124,39 +165,6 @@ const SockAddr &Socket::get_peer_address() const return *peer_addr; } -Socket::~Socket() -{ - close(); -} - -Socket::Socket(SocketHandle h, const SockAddr &paddr): - handle(h), - connected(true), - local_addr(0), - peer_addr(paddr.copy()) -{ - sockaddr sa; - socklen_t size=sizeof(sockaddr); - getsockname(handle, &sa, &size); - local_addr=SockAddr::create(sa); - -#ifdef WIN32 - event=CreateEvent(0, false, false, 0); -#endif -} - -Socket::Socket(Family af, int type, int proto): - connected(false), - local_addr(0), - peer_addr(0) -{ - handle=socket(af, type, proto); - -#ifdef WIN32 - event=CreateEvent(0, false, false, 0); -#endif -} - void Socket::check_state(bool conn) const { if(handle==MSP_NET_INVALID_SOCKET_HANDLE) @@ -165,7 +173,16 @@ void Socket::check_state(bool conn) const throw Exception("Socket is not connected"); } -int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) +int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) +{ +#ifdef WIN32 + return setsockopt(handle, level, optname, reinterpret_cast(optval), optlen); +#else + return setsockopt(handle, level, optname, optval, optlen); +#endif +} + +int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) const { #ifdef WIN32 return getsockopt(handle, level, optname, reinterpret_cast(optval), optlen);