X-Git-Url: http://git.tdb.fi/?p=libs%2Fnet.git;a=blobdiff_plain;f=source%2Fnet%2Fclientsocket.cpp;h=51a8dfa01b7913485397438ddcc3c24b5e9ae35b;hp=80303de7ea9a136aa61ce54337effb80e049d934;hb=HEAD;hpb=debe1004676d5431e571d9c4361072661dcc88c4 diff --git a/source/net/clientsocket.cpp b/source/net/clientsocket.cpp index 80303de..51a8dfa 100644 --- a/source/net/clientsocket.cpp +++ b/source/net/clientsocket.cpp @@ -1,26 +1,19 @@ -#ifdef WIN32 -#include -#else -#include -#include -#endif -#include +#include "platform_api.h" #include "clientsocket.h" +#include #include "socket_private.h" +using namespace std; + namespace Msp { namespace Net { ClientSocket::ClientSocket(Family af, int type, int proto): - Socket(af, type, proto), - connecting(false), - connected(false), - peer_addr(0) + Socket(af, type, proto) { } ClientSocket::ClientSocket(const Private &p, const SockAddr &paddr): Socket(p), - connecting(false), connected(true), peer_addr(paddr.copy()) { } @@ -28,61 +21,75 @@ ClientSocket::ClientSocket(const Private &p, const SockAddr &paddr): ClientSocket::~ClientSocket() { signal_flush_required.emit(); +} + +void ClientSocket::shutdown(IO::Mode m) +{ + int how; + m = m&IO::M_RDWR; +#ifdef _WIN32 + if(m==IO::M_READ) + how = SD_RECEIVE; + else if(m==IO::M_WRITE) + how = SD_SEND; + else if(m==IO::M_RDWR) + how = SD_BOTH; +#else + if(m==IO::M_READ) + how = SHUT_RD; + else if(m==IO::M_WRITE) + how = SHUT_WR; + else if(m==IO::M_RDWR) + how = SHUT_RDWR; +#endif + else + return; - delete peer_addr; + ::shutdown(priv->handle, how); + mode = mode&~m; } const SockAddr &ClientSocket::get_peer_address() const { - if(peer_addr==0) + if(!peer_addr) throw bad_socket_state("not connected"); return *peer_addr; } -unsigned ClientSocket::do_write(const char *buf, unsigned size) +size_t ClientSocket::do_write(const char *buf, size_t size) { + check_access(IO::M_WRITE); if(!connected) throw bad_socket_state("not connected"); if(size==0) return 0; - int ret = ::send(priv->handle, buf, size, 0); - if(ret<0) - { - if(errno==EAGAIN) - return 0; - else - throw system_error("send"); - } - - return ret; + return check_sys_error(::send(priv->handle, buf, size, 0), "send"); } -unsigned ClientSocket::do_read(char *buf, unsigned size) +size_t ClientSocket::do_read(char *buf, size_t size) { + check_access(IO::M_READ); if(!connected) throw bad_socket_state("not connected"); + // XXX This breaks level-triggered semantics on Windows if(size==0) return 0; - int ret = ::recv(priv->handle, buf, size, 0); - if(ret<0) - { - if(errno==EAGAIN) - return 0; - else - throw system_error("recv"); - } - else if(ret==0 && !eof_flag) + make_signed::type ret = ::recv(priv->handle, buf, size, 0); + if(ret==0) { - eof_flag = true; - signal_end_of_file.emit(); - set_events(IO::P_NONE); + if(!eof_flag) + { + set_socket_events(S_NONE); + set_eof(); + } + return 0; } - return ret; + return check_sys_error(ret, "recv"); } } // namespace Net