skstream
skstream.h
1 /**************************************************************************
2  FreeSockets - Portable C++ classes for IP(sockets) applications. (v0.3)
3  Copyright (C) 2000-2001 Rafael Guterres Jeffman
4  (C) 2002-2006 Alistair Riddoch
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20 **************************************************************************/
21 
29 #ifndef RGJ_FREE_STREAM_H_
30 #define RGJ_FREE_STREAM_H_
31 
32 #include <iostream>
33 
34 #include <skstream/sksocket.h>
35 
36 // To not include full <cstdio>, we define only EOF
37 #ifndef EOF
38 #define EOF (-1)
39 #endif
40 
42 // class socketbuf
44 
46 class socketbuf : public std::streambuf {
47 private:
48  std::streambuf::char_type *_buffer;
49 
50 protected:
51  SOCKET_TYPE _socket;
52 
53  timeval _underflow_timeout;
54  timeval _overflow_timeout;
55 
56 private:
58  socketbuf(const socketbuf&);
60  socketbuf& operator=(const socketbuf&);
61 
62 protected:
63  bool Timeout;
64 
65 public:
69  explicit socketbuf(SOCKET_TYPE sock, std::streamsize insize = 0x8000,
70  std::streamsize outsize = 0x8000);
74  socketbuf(SOCKET_TYPE sock, std::streambuf::char_type * buf,
75  std::streamsize length);
76 
78  virtual ~socketbuf();
79 
81  void setSocket(SOCKET_TYPE sock);
82 
84  SOCKET_TYPE getSocket() const {
85  return _socket;
86  }
87 
91  void setReadTimeout(unsigned sec, unsigned usec=0) {
92  _underflow_timeout.tv_sec = sec;
93  _underflow_timeout.tv_usec = usec;
94  }
95 
99  void setWriteTimeout(unsigned sec, unsigned usec=0) {
100  _overflow_timeout.tv_sec = sec;
101  _overflow_timeout.tv_usec = usec;
102  }
103 
104  void setTimeout(unsigned sec, unsigned usec=0) {
105  setWriteTimeout(sec, usec);
106  }
107 
109  bool timeout() const {
110  return Timeout;
111  }
112 
113 protected:
115  virtual int_type overflow(int_type nCh = traits_type::eof()) = 0;
117  virtual int_type underflow() = 0;
118 
120  virtual int sync();
121 
125  std::streambuf * setbuf(std::streambuf::char_type * buf, std::streamsize len);
126 };
127 
129 class stream_socketbuf : public socketbuf {
130 public:
134  explicit stream_socketbuf(SOCKET_TYPE sock,
135  std::streamsize insize = 0x8000,
136  std::streamsize outsize = 0x8000);
140  stream_socketbuf(SOCKET_TYPE sock, std::streambuf::char_type * buf,
141  std::streamsize length);
142 
144  virtual ~stream_socketbuf();
145 
146 protected:
148  virtual int_type overflow(int_type nCh = traits_type::eof());
150  virtual int_type underflow();
151 
152 };
153 
155 class dgram_socketbuf : public socketbuf {
156 public:
160  explicit dgram_socketbuf(SOCKET_TYPE sock, std::streamsize insize = 0x8000,
161  std::streamsize outsize = 0x8000);
165  dgram_socketbuf(SOCKET_TYPE sock,
166  std::streambuf::char_type * buf,
167  std::streamsize length);
168 
170  virtual ~dgram_socketbuf();
171 
172  bool setTarget(const std::string& address, unsigned port, int proto);
173 
174  void setOutpeer(const sockaddr_storage & peer) {
175  out_peer = peer;
176  }
177 
178  const sockaddr_storage & getOutpeer() const {
179  return out_peer;
180  }
181 
182  const sockaddr_storage & getInpeer() const {
183  return in_peer;
184  }
185 
186  SOCKLEN getOutpeerSize() const {
187  return out_p_size;
188  }
189 
190  SOCKLEN getInpeerSize() const {
191  return in_p_size;
192  }
193 
194 protected:
196  sockaddr_storage out_peer;
198  sockaddr_storage in_peer;
200  SOCKLEN out_p_size;
202  SOCKLEN in_p_size;
203 
205  virtual int_type overflow(int_type nCh = traits_type::eof());
207  virtual int_type underflow();
208 
209 };
210 
212 // class socket_stream
214 
216 class basic_socket_stream : public basic_socket, public std::iostream {
217 protected:
218  socketbuf & _sockbuf;
219  int m_protocol;
220 
221 public:
223  basic_socket_stream(socketbuf & buffer, int proto = FreeSockets::proto_IP);
224 
225  // Destructor
226  virtual ~basic_socket_stream();
227 
228  bool fail();
229 
230  bool operator!() {
231  return fail();
232  }
233 
234  bool timeout() const {
235  return _sockbuf.timeout();
236  }
237 
238  virtual SOCKET_TYPE getSocket() const;
239 
240  // Needs to be virtual to handle in-progress connect()'s for
241  // tcp sockets
242  virtual void close();
243 
244  void shutdown(bool wr_only = false);
245 
246  void setSocket(SOCKET_TYPE sock) {
247  _sockbuf.setSocket(sock);
248  }
249 
250  void setTimeout(unsigned sec, unsigned usec=0) {
251  _sockbuf.setTimeout(sec,usec);
252  }
253 
254  int getProtocol() const {
255  return m_protocol;
256  }
257 };
258 
260 // class stream_socket_stream
262 
264 private:
267 
268 protected:
269  SOCKET_TYPE _connecting_socket;
270 
272  stream_socket_stream(SOCKET_TYPE socket);
273 public:
274  virtual ~stream_socket_stream();
275 
276  virtual void close();
277  virtual SOCKET_TYPE getSocket() const;
278 
279  bool connect_pending() const {
280  return (_connecting_socket != INVALID_SOCKET);
281  }
282 };
283 
285 // class tcp_socket_stream
287 
288 struct addrinfo;
289 
292 private:
294 
296 
297  struct addrinfo * _connecting_address;
298  struct addrinfo * _connecting_addrlist;
299 
300 public:
302  tcp_socket_stream(SOCKET_TYPE socket);
303 
304  tcp_socket_stream(const std::string& address, int service,
305  bool nonblock = false);
306 
307  tcp_socket_stream(const std::string& address, int service,
308  unsigned int milliseconds);
309 
310  virtual ~tcp_socket_stream();
311 
312  int open(const std::string& address, int service, bool nonblock = false);
313  int open(const std::string& address, int service, unsigned int milliseconds);
314  int open(struct addrinfo *, bool nonblock = false);
315  int open_next();
316 
317  const std::string getRemoteHost(bool lookup = false) const;
318  const std::string getRemoteService(bool lookup = false) const;
319  bool isReady(unsigned int milliseconds = 0);
320 };
321 
324 private:
326 
328 
329 protected:
330  dgram_socketbuf & dgram_sockbuf;
331 
332  int bindToIpService(int service, int type, int protocol);
333 
334 public:
336 
337  virtual ~dgram_socket_stream();
338 
339  bool setTarget(const std::string& address, unsigned port) {
340  return dgram_sockbuf.setTarget(address, port, m_protocol);
341  }
342 
343  void setOutpeer(const sockaddr_storage& peer) {
344  return dgram_sockbuf.setOutpeer(peer);
345  }
346 
347  const sockaddr_storage & getOutpeer() const {
348  return dgram_sockbuf.getOutpeer();
349  }
350 
351  const sockaddr_storage & getInpeer() const {
352  return dgram_sockbuf.getInpeer();
353  }
354 
355  SOCKLEN getOutpeerSize() const {
356  return dgram_sockbuf.getOutpeerSize();
357  }
358 
359  SOCKLEN getInpeerSize() const {
360  return dgram_sockbuf.getInpeerSize();
361  }
362 };
363 
364 
366 // class udp_socket_stream
368 
371 private:
373 
375 
376 public:
378 
379  virtual ~udp_socket_stream();
380 
381  int open(int service);
382 };
383 
384 #ifdef SOCK_RAW
385 
387 // class raw_socket_stream
389 
391 class raw_socket_stream : public dgram_socket_stream {
392 private:
393  raw_socket_stream(const raw_socket_stream&);
394 
395  raw_socket_stream& operator=(const raw_socket_stream& socket);
396 
397 public:
398  raw_socket_stream(FreeSockets::IP_Protocol proto=FreeSockets::proto_RAW);
399 
400  virtual ~raw_socket_stream();
401 
402  void setProtocol(FreeSockets::IP_Protocol proto);
403 
404  bool setTarget(const std::string& address, unsigned port) {
405  return dgram_sockbuf.setTarget(address, port, m_protocol);
406  }
407 
408  bool setBroadcast(bool opt=false);
409 };
410 
411 #endif // SOCK_RAW
412 
413 #endif // RGJ_FREE_STREAM_H_
414 
An iostream class that handle TCP sockets.
Definition: skstream.h:291
virtual int_type overflow(int_type nCh=traits_type::eof())=0
Handle writing data from the buffer to the socket.
A stream buffer class that handles datagram sockets.
Definition: skstream.h:155
A base class for stream buffers that handle sockets.
Definition: skstream.h:46
SOCKLEN out_p_size
Size of target address.
Definition: skstream.h:200
std::streambuf * setbuf(std::streambuf::char_type *buf, std::streamsize len)
Definition: skstream.cpp:207
Definition: skstream.h:263
Base class for anything that encapsulates a socket.
Definition: sksocket.h:79
virtual int_type underflow()=0
Handle reading data from the socket to the buffer.
void setReadTimeout(unsigned sec, unsigned usec=0)
Definition: skstream.h:91
A base class for iostreams that handles stream sockets.
Definition: skstream.h:216
sockaddr_storage out_peer
Target address of datagrams sent via this stream.
Definition: skstream.h:196
void setSocket(SOCKET_TYPE sock)
Set the existing socket that this buffer should use.
Definition: skstream.cpp:187
An iostream class that handle IP datagram sockets.
Definition: skstream.h:323
socketbuf(const socketbuf &)
Not implemented. Copying a socket buffer is not permited.
socketbuf & operator=(const socketbuf &)
Not implemented. Copying a socket buffer is not permited.
SOCKET_TYPE getSocket() const
Get the socket that this buffer uses.
Definition: skstream.h:84
sockaddr_storage in_peer
Source address of last datagram received by this stream.
Definition: skstream.h:198
void setWriteTimeout(unsigned sec, unsigned usec=0)
Definition: skstream.h:99
bool timeout() const
Return the flag indicating whether a timeout has occured.
Definition: skstream.h:109
virtual int sync()
Flush the output buffer.
Definition: skstream.cpp:193
A stream buffer class that handles stream sockets.
Definition: skstream.h:129
SOCKLEN in_p_size
Size of source address.
Definition: skstream.h:202
An iostream class that handle UDP sockets.
Definition: skstream.h:370
virtual ~socketbuf()
Destroy the socket buffer.
Definition: skstream.cpp:179