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