Add support for unix sockets to Tairon::Net::Socket.
[tairon.git] / src / net-core / socket.h
bloba9e294dba4ecf17d546d3826524b08a452dd9b04
1 /***************************************************************************
2 * *
3 * Copyright (C) 2006 David Brodsky *
4 * *
5 * This library is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU Library General Public *
7 * License as published by the Free Software Foundation and appearing *
8 * in the file LICENSE.LGPL included in the packaging of this file. *
9 * *
10 * This library is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 * Library General Public License for more details. *
14 * *
15 ***************************************************************************/
17 #ifndef _tairon_net_core_socket_h
18 #define _tairon_net_core_socket_h
20 #include <sys/socket.h>
22 #include <tairon/core/exceptions.h>
23 #include <tairon/core/signals.h>
25 using Tairon::Core::String;
27 namespace Tairon
30 namespace Net
33 class SocketNotifier;
35 /** \brief This class provides non-blocking network connection.
37 * Socket's family can be Unix for local communication through unix sockets or
38 * IPv4 for communication using protocol with the same name.
40 * Socket type can be either a stream (for reliable connection-based byte
41 * streams) or a datagram (for connectionless, unreliable messages). When new
42 * data is incoming readyRead signal is emitted and the data can be read with
43 * readAll() method which reads all the data from socket. In some cases better
44 * performance can be achieved with readTo() method which reads not more than
45 * given amount of data into specified location in memory (this can be a mmaped
46 * file, so no data copying occurs at all).
48 * If an error occurs either an exception is thrown or signal is emitted. It is
49 * necessary to close the socket in both cases. The socket is deleted by
50 * Poll::poll() after it is closed.
52 class Socket
54 public:
55 /** Family of the socket.
57 enum Family {
58 /** Unix socket (only local connections).
60 Unix = PF_UNIX,
62 /** IPv4 socket.
64 IPv4 = PF_INET
67 /** Type of the socket.
69 enum Type {
70 /** Stream data (TCP connection).
72 Stream = SOCK_STREAM,
74 /** Datagrams (UDP packets).
76 Datagram = SOCK_DGRAM
79 static const size_t bufLength;
81 /** Creates new socket of given type.
83 Socket(Family family, Type type);
85 /** Creates new socket object associated with given descriptor.
87 Socket(int sd);
89 /** Closes socket and frees all resources.
91 ~Socket();
93 /** Closes the socket and destroys the object.
95 void close();
97 /** Connects this socket to a unix socket.
99 * \param path Path to the unix socket.
101 void connect(const String &path);
103 /** Connects this socket (with IPv4 family) to a host.
105 * \param address Host to which this socket should be connected.
106 * \param port Target port of the connection in host byte order.
108 void connect(const String &address, uint16_t port);
110 /** Returns descriptor of this socket.
112 int getDescriptor() {
113 return fd;
116 /** Reads data from the socket. This method never blocks. This
117 * method throws a SocketException when the socket has been closed.
119 * \param max number of bytes to read. If this number is greater than
120 * the size of the internal buffer, then data that fits into the
121 * internal buffer are returned.
123 String read(size_t max = bufLength);
125 /** Reads data from the socket and stores them in the buffer. This
126 * method throws a SocketException when the socket has been closed.
128 * \param buf Target buffer for the data.
129 * \param length Length of the buffer.
131 size_t readTo(void *buf, size_t length);
133 /** Tells this socket that all setup has been done.
135 void ready();
137 /** Writes data to the socket and returns the number of characters
138 * written to the socket.
140 * \param data Data to write.
141 * \param block If it is set to true then the operation will block when
142 * it cannot be processed completely.
144 size_t write(const String &data, bool block = true);
146 /** Writes data to the socket and returns the number of characters
147 * written to the socket.
149 * \param data Data to write.
150 * \param length Length of data.
151 * \param block If it is set to true then the operation will block when
152 * it cannot be processed completely.
154 size_t write(const char *data, size_t length, bool block = true);
156 public:
157 /** This signal is emitted when the socket is connected to the host.
158 * The receiver gets as the first parameter pointer to this socket.
160 Tairon::Core::DSignal1<Socket *> connectedSignal;
162 /** This signal is emitted when an error occurs. The receiver gets as
163 * the first parameter pointer to this socket and the second one is
164 * error code. The receiver must close the socket after receiving this
165 * signal.
167 Tairon::Core::DSignal2<Socket *, int> errorSignal;
169 /** This signal is emitted when there is incoming data. The receiver
170 * gets as the first parameter pointer to this socket.
172 Tairon::Core::DSignal1<Socket *> readyReadSignal;
174 /** This signal is emitted when the socket is ready to write data. The
175 * receiver gets as the first parameter pointer to this socket.
177 Tairon::Core::DSignal1<Socket *> readyWriteSignal;
179 private:
180 /** Initializes private data.
182 inline void init();
184 /** Calls connected signal with this class as the first parameter.
186 void connected();
188 /** Gets an error number end emits errorSignal.
190 void error();
192 /** Invokes ready read signal with this class as the first parameter.
194 void readyRead();
196 /** Cals readyWriteSignal.
198 void readyWrite();
200 private:
201 /** Functor for calling connected method.
203 Tairon::Core::Functor0<void> *connectedFunctor;
205 /** Socket descriptor.
207 int fd;
209 /** Buffer for input data.
211 char *inBuffer;
213 /** Notifier of this socket.
215 SocketNotifier *notifier;
217 /** Functor for calling readyWrite method.
219 Tairon::Core::Functor0<void> *readyWriteFunctor;
221 friend class Tairon::Core::MethodFunctor0<void, Socket>;
224 /** \brief Exception for socket errors.
226 class SocketException : public Tairon::Core::Exception
228 public:
229 /** Constructor that takes as parameters description of the exception
230 * and its error number.
232 SocketException(const String &desc, int err);
234 /** Standard destructor.
236 virtual ~SocketException() {};
238 /** Returns error number of the exception.
240 int getErrorNumber() const {
241 return errorNumber;
244 private:
245 /** Error number of this exception.
247 int errorNumber;
250 }; // namespace Net
252 }; // namespace Tairon
254 #endif
256 // vim: ai sw=4 ts=4 noet fdm=marker