]> git.tdb.fi Git - libs/net.git/blob - source/net/datagramsocket.cpp
Prepare for assimilating msphttp
[libs/net.git] / source / net / datagramsocket.cpp
1 #include <cerrno>
2 #include <msp/core/systemerror.h>
3 #include <msp/io/handle_private.h>
4 #include <msp/strings/format.h>
5 #include "datagramsocket.h"
6 #include "sockaddr_private.h"
7 #include "socket_private.h"
8
9 namespace Msp {
10 namespace Net {
11
12 DatagramSocket::DatagramSocket(Family f, int p):
13         ClientSocket(f, SOCK_DGRAM, p)
14 {
15 #ifdef WIN32
16         WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
17 #endif
18         set_events(IO::P_INPUT);
19 }
20
21 bool DatagramSocket::connect(const SockAddr &addr)
22 {
23         SockAddr::SysAddr sa = addr.to_sys();
24
25         int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
26         if(err==-1)
27         {
28 #ifdef WIN32
29                 throw system_error("connect", WSAGetLastError());
30 #else
31                 throw system_error("connect");
32 #endif
33         }
34
35         delete peer_addr;
36         peer_addr = addr.copy();
37
38         delete local_addr;
39         SockAddr::SysAddr lsa;
40         getsockname(priv->handle, reinterpret_cast<sockaddr *>(&lsa.addr), &lsa.size);
41         local_addr = SockAddr::new_from_sys(lsa);
42
43         connected = true;
44
45         return true;
46 }
47
48 unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &addr)
49 {
50         if(size==0)
51                 return 0;
52
53         SockAddr::SysAddr sa = addr.to_sys();
54
55         int ret = ::sendto(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
56         if(ret<0)
57         {
58                 if(errno==EAGAIN)
59                         return 0;
60                 else
61                 {
62 #ifdef WIN32
63                         throw system_error("sendto", WSAGetLastError());
64 #else
65                         throw system_error("sendto");
66 #endif
67                 }
68         }
69
70         return ret;
71 }
72
73 unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&from_addr)
74 {
75         if(size==0)
76                 return 0;
77
78         SockAddr::SysAddr sa;
79         int ret = ::recvfrom(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&sa.addr), &sa.size);
80         if(ret<0)
81         {
82                 if(errno==EAGAIN)
83                         return 0;
84                 else
85                 {
86 #ifdef WIN32
87                         throw system_error("recvfrom", WSAGetLastError());
88 #else
89                         throw system_error("recvfrom");
90 #endif
91                 }
92         }
93
94         from_addr = SockAddr::new_from_sys(sa);
95
96         return ret;
97 }
98
99 } // namespace Net
100 } // namespace Msp