-#ifdef WIN32
-#include <winsock2.h>
-#else
-#include <cerrno>
-#include <sys/socket.h>
-#endif
-#include <msp/core/systemerror.h>
+#include "platform_api.h"
#include "clientsocket.h"
+#include <msp/core/systemerror.h>
#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())
{ }
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");
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<size_t>::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