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