]> git.tdb.fi Git - libs/net.git/blobdiff - source/net/clientsocket.cpp
Prepare for assimilating msphttp
[libs/net.git] / source / net / clientsocket.cpp
diff --git a/source/net/clientsocket.cpp b/source/net/clientsocket.cpp
new file mode 100644 (file)
index 0000000..80303de
--- /dev/null
@@ -0,0 +1,89 @@
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <cerrno>
+#include <sys/socket.h>
+#endif
+#include <msp/core/systemerror.h>
+#include "clientsocket.h"
+#include "socket_private.h"
+
+namespace Msp {
+namespace Net {
+
+ClientSocket::ClientSocket(Family af, int type, int proto):
+       Socket(af, type, proto),
+       connecting(false),
+       connected(false),
+       peer_addr(0)
+{ }
+
+ClientSocket::ClientSocket(const Private &p, const SockAddr &paddr):
+       Socket(p),
+       connecting(false),
+       connected(true),
+       peer_addr(paddr.copy())
+{ }
+
+ClientSocket::~ClientSocket()
+{
+       signal_flush_required.emit();
+
+       delete peer_addr;
+}
+
+const SockAddr &ClientSocket::get_peer_address() const
+{
+       if(peer_addr==0)
+               throw bad_socket_state("not connected");
+       return *peer_addr;
+}
+
+unsigned ClientSocket::do_write(const char *buf, unsigned size)
+{
+       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;
+}
+
+unsigned ClientSocket::do_read(char *buf, unsigned size)
+{
+       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)
+       {
+               eof_flag = true;
+               signal_end_of_file.emit();
+               set_events(IO::P_NONE);
+       }
+
+       return ret;
+}
+
+} // namespace Net
+} // namespace Msp