17 #define closesocket close |
21 #define closesocket close |
18 #else |
22 #else |
19 #error "This network code won't compile on win32 :)" |
23 #error "This network code won't compile on win32 :)" |
20 #endif |
24 #endif |
21 |
25 |
22 #include <cerrno> |
|
23 #include <cstring> |
|
24 |
|
25 /** |
26 /** |
26 * We use ClanLib's Socket API, but with our own extensions... |
27 * We use ClanLib's Socket API, but with our own extensions... |
27 */ |
28 */ |
28 class NetworkSocket { |
29 class NetworkSocket { |
29 private: |
30 private: |
|
31 /** |
|
32 * Socket family/type/protocol |
|
33 */ |
|
34 struct socket_type { |
|
35 /** Socket domain */ |
|
36 int family; |
|
37 |
|
38 /** Socket type */ |
|
39 int socktype; |
|
40 |
|
41 /** Socket protocol */ |
|
42 int protocol; |
|
43 |
|
44 /** Simple constructor */ |
|
45 socket_type (int family = 0, int socktype = 0, int protocol = 0) : family(family), socktype(socktype), protocol(protocol) { } |
|
46 }; |
|
47 |
|
48 /** These are nonzero if given via the constructor, used to filter out unwanted addrinfos */ |
|
49 socket_type sock_type; |
|
50 |
30 /** The file descriptor */ |
51 /** The file descriptor */ |
31 int fd; |
52 int fd; |
32 |
53 |
33 /** Socket domain */ |
54 /** Our current type, intialized via constructor, but updated by lazy_socket */ |
34 int family; |
55 socket_type type; |
35 |
|
36 /** Socket type */ |
|
37 int socktype; |
|
38 |
|
39 /** Socket protocol */ |
|
40 int protocol; |
|
41 |
56 |
42 /** |
57 /** |
43 * Has the socket been explicitly bind()'d? If so, force ourselves to use this socket in connect(). |
58 * Has the socket been explicitly bind()'d? If so, force ourselves to use this socket in connect(). |
44 */ |
59 */ |
45 bool bound; |
60 bool bound : 1; |
|
61 |
|
62 /** |
|
63 * Registered to reactor? |
|
64 */ |
|
65 bool registered : 1; |
|
66 |
|
67 /** |
|
68 * Do we want to know about recv()s? |
|
69 */ |
|
70 bool want_read : 1; |
|
71 |
|
72 /** |
|
73 * Is the write buffer full? |
|
74 */ |
|
75 bool want_write : 1; |
|
76 |
|
77 /** |
|
78 * The reactor that we use, defaults to NetworkReactor::current |
|
79 */ |
|
80 NetworkReactor *reactor; |
46 |
81 |
47 /** |
82 /** |
48 * Read/write signals |
83 * Read/write signals |
49 */ |
84 */ |
50 CL_Signal_v0 _sig_read, _sig_write; |
85 CL_Signal_v0 _sig_read, _sig_write; |
51 |
86 |
52 public: |
87 public: |
53 /** |
88 /** |
54 * Construct a socket of the specific type. Family and protocol can be left as NULL, but type should usually |
89 * Construct a socket of the specific type. Family and protocol can be left as NULL, but type should usually |
55 * be specified. |
90 * be specified. The given reactor is used for polling, defaults to NetworkReactor::current |
56 */ |
91 */ |
57 NetworkSocket (int family, int socktype, int protocol = 0); |
92 NetworkSocket (int family, int socktype, int protocol = 0, NetworkReactor *reactor = NULL); |
58 |
93 |
59 /** |
94 /** |
60 * Create a socket from the given pre-existing fd |
95 * Create a socket from the given pre-existing fd |
61 */ |
96 */ |
62 NetworkSocket (int fd); |
97 NetworkSocket (int fd, socket_type type, NetworkReactor *reactor = NULL); |
63 |
98 |
64 /** |
99 /** |
65 * Force-close the socket if it's still open |
100 * Force-close the socket if it's still open |
66 */ |
101 */ |
67 ~NetworkSocket (void); |
102 ~NetworkSocket (void); |
68 |
103 |
69 private: |
104 private: |
70 // XXX: nocopy |
105 // XXX: nocopy |
71 |
106 |
72 /** |
107 /** |
|
108 * Reset bound+poll |
|
109 */ |
|
110 void reset (void); |
|
111 |
|
112 /** |
73 * Create a new socket of the given type, unless we already have one |
113 * Create a new socket of the given type, unless we already have one |
74 */ |
114 */ |
75 void lazy_socket (int family, int type, int protocol); |
115 void lazy_socket (int family, int type, int protocol); |
76 |
116 |
77 /** |
117 /** |
78 * Close, ignoring errors |
118 * Close and reset, ignoring errors |
79 */ |
119 */ |
80 void force_close (void); |
120 void force_close (void); |
81 |
121 |
82 public: |
122 public: |
83 /** |
123 /** |
149 |
189 |
150 /** |
190 /** |
151 * Triggered when socket becomes writeable after a send that returned zero |
191 * Triggered when socket becomes writeable after a send that returned zero |
152 */ |
192 */ |
153 CL_Signal_v0& sig_write (void) { return _sig_write; } |
193 CL_Signal_v0& sig_write (void) { return _sig_write; } |
|
194 |
|
195 /** |
|
196 * Register to NetworkReactor unless already registered |
|
197 */ |
|
198 void register_poll (void); |
|
199 |
|
200 /** |
|
201 * Trigger sig_read() once socket is ready for recv? |
|
202 */ |
|
203 void set_poll_read (bool want_read) { this->want_read = want_read; if (!registered) register_poll(); } |
|
204 |
|
205 /** |
|
206 * Trigger sig_write() once socket is ready for send? |
|
207 */ |
|
208 void set_poll_write (bool want_write) { this->want_write = want_write; if (!registered) register_poll(); } |
|
209 |
|
210 /** |
|
211 * What events this socket is interested in. |
|
212 */ |
|
213 NetworkPollMask get_poll (void) { |
|
214 return (want_read ? POLL_READ : 0) | (want_write ? POLL_WRITE : 0); |
|
215 } |
|
216 |
|
217 /** |
|
218 * Notify of events |
|
219 */ |
|
220 void notify (NetworkPollMask mask) { |
|
221 if (mask & POLL_READ) _sig_read(); |
|
222 if (mask & POLL_WRITE) _sig_write(); |
|
223 } |
154 }; |
224 }; |
155 |
225 |
156 /** |
226 /** |
157 * Base class for expcetions thrown by socket methods |
227 * Base class for expcetions thrown by socket methods |
158 */ |
228 */ |