]> git.tdb.fi Git - libs/net.git/blob - source/net/clientsocket.cpp
Prepare for assimilating msphttp
[libs/net.git] / source / net / clientsocket.cpp
1 #ifdef WIN32
2 #include <winsock2.h>
3 #else
4 #include <cerrno>
5 #include <sys/socket.h>
6 #endif
7 #include <msp/core/systemerror.h>
8 #include "clientsocket.h"
9 #include "socket_private.h"
10
11 namespace Msp {
12 namespace Net {
13
14 ClientSocket::ClientSocket(Family af, int type, int proto):
15         Socket(af, type, proto),
16         connecting(false),
17         connected(false),
18         peer_addr(0)
19 { }
20
21 ClientSocket::ClientSocket(const Private &p, const SockAddr &paddr):
22         Socket(p),
23         connecting(false),
24         connected(true),
25         peer_addr(paddr.copy())
26 { }
27
28 ClientSocket::~ClientSocket()
29 {
30         signal_flush_required.emit();
31
32         delete peer_addr;
33 }
34
35 const SockAddr &ClientSocket::get_peer_address() const
36 {
37         if(peer_addr==0)
38                 throw bad_socket_state("not connected");
39         return *peer_addr;
40 }
41
42 unsigned ClientSocket::do_write(const char *buf, unsigned size)
43 {
44         if(!connected)
45                 throw bad_socket_state("not connected");
46
47         if(size==0)
48                 return 0;
49
50         int ret = ::send(priv->handle, buf, size, 0);
51         if(ret<0)
52         {
53                 if(errno==EAGAIN)
54                         return 0;
55                 else
56                         throw system_error("send");
57         }
58
59         return ret;
60 }
61
62 unsigned ClientSocket::do_read(char *buf, unsigned size)
63 {
64         if(!connected)
65                 throw bad_socket_state("not connected");
66
67         if(size==0)
68                 return 0;
69
70         int ret = ::recv(priv->handle, buf, size, 0);
71         if(ret<0)
72         {
73                 if(errno==EAGAIN)
74                         return 0;
75                 else
76                         throw system_error("recv");
77         }
78         else if(ret==0 && !eof_flag)
79         {
80                 eof_flag = true;
81                 signal_end_of_file.emit();
82                 set_events(IO::P_NONE);
83         }
84
85         return ret;
86 }
87
88 } // namespace Net
89 } // namespace Msp