feisty meow concerns codebase 2.140
spocket.h
Go to the documentation of this file.
1#ifndef SPOCKET_CLASS
2#define SPOCKET_CLASS
3
4/*****************************************************************************\
5* *
6* Name : spocket *
7* Author : Chris Koeritz *
8* *
9* Purpose: *
10* *
11* *
12*******************************************************************************
13* Copyright (c) 1989-$now By Author. This program is free software; you can *
14* redistribute it and/or modify it under the terms of the GNU General Public *
15* License as published by the Free Software Foundation; either version 2 of *
16* the License or (at your option) any later version. This is online at: *
17* http://www.fsf.org/copyleft/gpl.html *
18* Please send any updates to: fred@gruntose.com *
19\*****************************************************************************/
20
21#include "tcpip_stack.h"
22
23#include <basis/contracts.h>
24#include <basis/mutex.h>
25#include <timely/time_stamp.h>
26
27namespace sockets {
28
29// forward declarations.
30class internet_address;
31class raw_socket;
32
34
39class spocket : public virtual basis::root_object
40{
41public:
43 CONNECTED, // connected socket over TCP.
44 BROADCAST, // broadcasting socket over UDP.
45 UNICAST, // single-address targeted socket over UDP.
46 BOGUS_SOCK // special type that goes nowhere and provides no data.
47 };
48
50 // constructs the spocket object. "where" provides the network location
51 // for either this side (for a server) or the other side (for a client).
52 // the decision about this socket's orientation (client or server) will not
53 // be made until either connect() or accept() are invoked. note however
54 // that BROADCAST sockets are only appropriate for use as a client; they
55 // can receive and send broadcasts that way without needing a server role.
56
57 ~spocket();
58 // drops any connection that was made and destroys the spocket object.
59
61
62 bool healthy();
63 // returns true if the spocket seems to be okay.
64
65 const internet_address &where() const;
66 // returns the location where this socket exists.
67
68 const internet_address &remote() const;
69 // returns the location that we have accepted from.
70
71 enum outcomes {
72 OKAY = basis::common::OKAY,
73 TIMED_OUT = basis::common::TIMED_OUT,
74 ACCESS_DENIED = basis::common::ACCESS_DENIED,
75 BAD_INPUT = basis::common::BAD_INPUT,
76 NONE_READY = basis::common::NONE_READY,
77 PARTIAL = basis::common::PARTIAL,
78
79 NO_CONNECTION = sockets::communication_commons::NO_CONNECTION,
80 NO_ANSWER = sockets::communication_commons::NO_ANSWER,
81
82 DEFINE_OUTCOME(NOT_SERVER, -39, "Accept was tried on a spocket that is "
83 "not a root server")
84 };
85
86 static const char *outcome_name(const basis::outcome &to_name);
87 // returns the text for "to_name" if it's a member of spocket outcomes.
88
89 // informative functions...
90
92 // returns a readable version of the contents of the spocket.
93
94 bool was_connected() const { return _was_connected; }
95 // a simple check of whether a connection has been made on this object.
96 // if this is not true, then the object is not usable yet. this state
97 // will also get set to false when the spocket gets disconnected.
98
99 bool connected();
100 // returns true if the spocket is "currently" connected. this causes an
101 // interrogation of the operating system and may take a short while.
102
103 // these report what type of spocket this is.
104 bool is_client() const { return _client; }
105 bool is_server() const { return !_client; }
106 bool is_root_server() const { return is_server() && !!_server_socket; }
107
108 basis::un_int OS_socket() { return _socket; }
109 // returns the low-level operating system form of our normal action socket.
110 // this is zero for a root server. note: this will still record what the
111 // socket was after it is closed out, just for record keeping; do not
112 // control the returned socket outside of this class.
113 basis::un_int OS_root_socket() { return _server_socket; }
114 // returns the OS form of our server socket, but only if this is a root
115 // server type of socket.
116
117 void bind_client(const internet_address &source);
119
123 // major operations for connected mode sockets...
124
125 basis::outcome connect(int communication_wait = 20 * basis::SECOND_ms);
126 // acts as a client and connects to a destination. the timeout is
127 // specified in milliseconds by "communication_wait". this can be as low
128 // as zero if you don't want to wait. TIMED_OUT is returned if the
129 // connection hasn't finished within the connection_wait. OKAY is returned
130 // if the connection succeeded. other outcomes denote failures.
131
132 basis::outcome accept(spocket * &sock, bool wait);
133 // makes this spocket act as a root server and accepts a connection from a
134 // client if possible. a root server is a spocket object that manages a
135 // server spocket but which does not allow any normal sending or receiving.
136 // only root servers can have accept called on them. the "sock" will be
137 // a normal server spocket which can be used to send and receive if it
138 // got connected. for "sock" to be valid, it must return as NULL_POINTER
139 // and the returned outcome must be OKAY. if no new connections are
140 // available, then NO_CONNECTION is returned. if the "wait" flag is true,
141 // then the accept on the root server will block until a connection is
142 // accepted and the returned spocket will be made non-blocking. if "wait"
143 // is false, then no blocking will occur at all. note that multiple
144 // threads can invoke this without tripping over the protective locking;
145 // once the root socket is initialized, accept will not lock the spocket.
146
148 // closes the connection. the state is returned to the post-construction
149 // state, i.e. it will appear that this object had never connected yet.
150
151 // these report which side of the connection this is functioning as.
152 bool client() const { return _client; }
153 bool server() const { return !_client; }
154
155 // send and receive functions...
156 //
157 // if the outcome from one of these is NO_CONNECTION, then somehow the
158 // connection has dropped or never succeeded.
159
160 basis::outcome send(const basis::abyte *buffer, int size, int &len_sent);
161 // sends "size" bytes from the "buffer". the number actually sent is
162 // stored in "len_sent". this can only be used for CONNECTED type sockets.
163
164 basis::outcome send(const basis::byte_array &to_send, int &len_sent);
165 // this version takes a byte_array.
166
167 basis::outcome send_to(const internet_address &where_to, const basis::abyte *buffer,
168 int size, int &len_sent);
169 // this version is used for sending when the socket type is BROADCAST
170 // or UNICAST.
171
172 basis::outcome send_to(const internet_address &where_to, const basis::byte_array &to_send,
173 int &len_sent);
174 // clone of above, using byte_array.
175
176 basis::outcome receive(basis::abyte *buffer, int &size);
177 // attempts to retrieve data from the spocket and place it in the "buffer".
178 // the "size" specifies how much space is available. if successful, the
179 // buffer will be filled with data and "size" will report how much there
180 // actually is.
181
182 basis::outcome receive(basis::byte_array &buffer, int &size);
183 // this version uses a byte_array for the "buffer". the "size" expected
184 // must still be set and "size" will still report the bytes read.
185//hmmm: could remove the size parameter for byte array type.
186
187 // these methods are used for BROADCAST and other non-connected types of
188 // spockets. they report the data as the above receive methods do, but they
189 // also report the sender.
190 basis::outcome receive_from(basis::abyte *buffer, int &size,
191 internet_address &where_from);
193 internet_address &where_from);
194
195 basis::outcome await_readable(int timeout);
196 // pauses this caller until data arrives. this is a blocking call that
197 // could potentially not return until the "timeout" elapses (measured in
198 // milliseconds). if "timeout" is zero, then this really doesn't do
199 // anything. if data is available, then OKAY is returned.
200
201 basis::outcome await_writable(int timeout);
202 // pauses this caller until the socket can be written to again. could
203 // potentially not return until the "timeout" elapses (measured in
204 // milliseconds). if "timeout" is zero, then this really doesn't do
205 // anything. if the socket is able to send again, then OKAY is returned.
206 // otherwise NONE_READY is returned.
207
208 tcpip_stack &stack() const;
209 // provides access to the spocket's tcpip stack to derivative objects.
210
211 bool is_bogus() const { return _type == BOGUS_SOCK; }
213
219private:
220 sock_types _type; // records what kind of socket we'll create.
221 basis::un_int _socket; // our socket that we communicate on.
222 basis::un_int _server_socket; // our serving socket, if we're a root server.
223 bool _was_connected; // did we ever successfully connect?
224 bool _client; // true if we are acting as a client.
225 internet_address *_where; // our addressing info.
226 internet_address *_remote; // our addressing info.
227 raw_socket *_socks; // provides low-level socket functionality.
228 tcpip_stack *_stack; // provides access to socket facilities.
229 basis::mutex *_select_lock; // protects concurrent access to socket.
230 timely::time_stamp *_last_resolve;
231 // tracks when we last tried a resolve on our address. if they try to
232 // reconnect and we haven't done this in a while, we'll re-resolve the
233 // socket.
234 bool _client_bind;
235 internet_address *_cli_bind;
236
237 // not allowed.
238 spocket(const spocket &);
239 spocket &operator =(const spocket &);
240};
241
242} //namespace.
243
244#endif
245
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
A very common template for a dynamic array of bytes.
Definition byte_array.h:36
Outcomes describe the state of completion for an operation.
Definition outcome.h:31
this type of address describes a destination out on the internet.
Abstraction for a higher-level BSD socket that is platform independent.
Definition spocket.h:40
basis::outcome await_writable(int timeout)
Definition spocket.cpp:256
bool was_connected() const
Definition spocket.h:94
tcpip_stack & stack() const
Definition spocket.cpp:150
bool client() const
Definition spocket.h:152
bool server() const
Definition spocket.h:153
basis::outcome send(const basis::abyte *buffer, int size, int &len_sent)
Definition spocket.cpp:573
basis::astring text_form()
Definition spocket.cpp:154
basis::outcome connect(int communication_wait=20 *basis::SECOND_ms)
Definition spocket.cpp:274
static const char * outcome_name(const basis::outcome &to_name)
Definition spocket.cpp:180
basis::un_int OS_socket()
Definition spocket.h:108
basis::outcome receive_from(basis::abyte *buffer, int &size, internet_address &where_from)
Definition spocket.cpp:713
bool is_root_server() const
Definition spocket.h:106
basis::outcome send_to(const internet_address &where_to, const basis::abyte *buffer, int size, int &len_sent)
Definition spocket.cpp:628
basis::outcome accept(spocket *&sock, bool wait)
Definition spocket.cpp:460
bool is_server() const
Definition spocket.h:105
const internet_address & remote() const
Definition spocket.cpp:148
void bind_client(const internet_address &source)
when a client calls connect, this forces it to bind to "source".
Definition spocket.cpp:174
basis::outcome disconnect()
Definition spocket.cpp:188
basis::outcome await_readable(int timeout)
Definition spocket.cpp:238
bool is_bogus() const
returns true when this object is bogus.
Definition spocket.h:211
basis::un_int OS_root_socket()
Definition spocket.h:113
DEFINE_CLASS_NAME("spocket")
const internet_address & where() const
Definition spocket.cpp:147
basis::outcome receive(basis::abyte *buffer, int &size)
Definition spocket.cpp:664
bool is_client() const
Definition spocket.h:104
Helpful functions for interacting with TCP/IP stacks.
Definition tcpip_stack.h:38
Represents a point in time relative to the operating system startup time.
Definition time_stamp.h:38
unsigned char abyte
A fairly important unit which is seldom defined...
Definition definitions.h:51
const int SECOND_ms
Number of milliseconds in a second.
unsigned int un_int
Abbreviated name for unsigned integers.
Definition definitions.h:62
Provides access to the operating system's socket methods.