]> git.tdb.fi Git - libs/net.git/blob - source/datagramsocket.cpp
Exception changes
[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         check_state(false);
21
22         sockaddr_storage sa;
23         socklen_t size = addr.fill_sockaddr(sa);
24
25         int err = ::connect(handle, reinterpret_cast<sockaddr *>(&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         size = sizeof(sockaddr_storage);
40         getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
41         local_addr = SockAddr::create(sa);
42
43         connected = true;
44
45         return (err==0)?0:1;
46 }
47
48 unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &addr_)
49 {
50         check_state(false);
51
52         if(size==0)
53                 return 0;
54
55         sockaddr_storage addr;
56         socklen_t addr_len = addr_.fill_sockaddr(addr);
57
58         int ret = ::sendto(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
59         if(ret<0)
60         {
61                 if(errno==EAGAIN)
62                         return 0;
63                 else
64                 {
65 #ifdef WIN32
66                         throw system_error("sendto", WSAGetLastError());
67 #else
68                         throw system_error("sendto");
69 #endif
70                 }
71         }
72
73         return ret;
74 }
75
76 unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&addr_)
77 {
78         check_state(false);
79
80         if(size==0)
81                 return 0;
82
83         sockaddr_storage addr;
84         socklen_t addr_len = sizeof(sockaddr_storage);
85
86         int ret = ::recvfrom(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
87         if(ret<0)
88         {
89                 if(errno==EAGAIN)
90                         return 0;
91                 else
92                 {
93 #ifdef WIN32
94                         throw system_error("recvfrom", WSAGetLastError());
95 #else
96                         throw system_error("recvfrom");
97 #endif
98                 }
99         }
100
101         addr_ = SockAddr::create(addr);
102
103         return ret;
104 }
105
106 } // namespace Net
107 } // namespace Msp