]> git.tdb.fi Git - libs/net.git/blobdiff - source/datagramsocket.cpp
Initial revision
[libs/net.git] / source / datagramsocket.cpp
diff --git a/source/datagramsocket.cpp b/source/datagramsocket.cpp
new file mode 100644 (file)
index 0000000..1394ffa
--- /dev/null
@@ -0,0 +1,95 @@
+/* $Id$
+
+This file is part of libmspnet
+Copyright © 2008  Mikkosoft Productions, Mikko Rasa
+Distributed under the LGPL
+*/
+
+#include <errno.h>
+#include <msp/strings/formatter.h>
+#include "datagramsocket.h"
+
+namespace Msp {
+namespace Net {
+
+DatagramSocket::DatagramSocket(Family f, int p):
+       Socket(f, SOCK_DGRAM, p)
+{ }
+
+int DatagramSocket::connect(const SockAddr &addr)
+{
+       check_state(false);
+
+       sockaddr sa;
+       socklen_t size=addr.fill_sockaddr(sa);
+
+       int err=::connect(handle, &sa, size);
+       if(err==-1)
+               throw Exception(format("Unable to connect: %s", strerror(errno)));
+
+       delete peer_addr;
+       peer_addr=addr.copy();
+
+       delete local_addr;
+       size=sizeof(sockaddr);
+       getsockname(handle, &sa, &size);
+       local_addr=SockAddr::create(sa);
+
+       connected=true;
+
+       return (err==0)?0:1;
+}
+
+unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &addr_)
+{
+       check_state(false);
+
+       if(size==0)
+               return 0;
+
+       sockaddr addr;
+       socklen_t addr_len=addr_.fill_sockaddr(addr);
+
+       int ret=::sendto(handle, buf, size, 0, &addr, addr_len);
+       if(ret<0)
+       {
+               if(errno==EAGAIN)
+                       return 0;
+               else
+                       throw Exception(format("Sendto failed: %s", strerror(errno)));
+       }
+
+       return ret;
+}
+
+unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&addr_)
+{
+       check_state(false);
+
+       if(size==0)
+               return 0;
+
+       sockaddr addr;
+       socklen_t addr_len=sizeof(sockaddr);
+
+       int ret=::recvfrom(handle, buf, size, 0, &addr, &addr_len);
+       if(ret<0)
+       {
+               if(errno==EAGAIN)
+                       return 0;
+               else
+                       throw Exception(format("Recvfrom failed: %s", strerror(errno)));
+       }
+
+       addr_=SockAddr::create(addr);
+
+       return ret;
+}
+
+IO::PollEvent DatagramSocket::get_initial_events() const
+{
+       return IO::P_INPUT;
+}
+
+} // namespace Net
+} // namespace Msp