00001 /** 00002 * @file scim_socket.h 00003 * @brief Socket interfaces. 00004 */ 00005 00006 /* 00007 * Smart Common Input Method 00008 * 00009 * Copyright (c) 2004 James Su <suzhe@turbolinux.com.cn> 00010 * Copyright (c) 2003 James Su <suzhe@turbolinux.com.cn> 00011 * Copyright (c) 2002 James Su <suzhe@turbolinux.com.cn> 00012 * 00013 * 00014 * This library is free software; you can redistribute it and/or 00015 * modify it under the terms of the GNU Lesser General Public 00016 * License as published by the Free Software Foundation; either 00017 * version 2 of the License, or (at your option) any later version. 00018 * 00019 * This library is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU Lesser General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public 00025 * License along with this program; if not, write to the 00026 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 00027 * Boston, MA 02111-1307 USA 00028 * 00029 * $Id: scim_socket.h,v 1.17 2004/06/19 12:58:00 suzhe Exp $ 00030 */ 00031 00032 #ifndef __SCIM_SOCKET_H 00033 #define __SCIM_SOCKET_H 00034 00035 namespace scim { 00036 00037 /** 00038 * @addtogroup SocketCommunication 00039 * @{ 00040 */ 00041 00042 class Socket; 00043 class SocketAddress; 00044 class SocketServer; 00045 class SocketClient; 00046 00047 typedef Slot2<void, SocketServer *, const Socket &> 00048 SocketServerSlotSocket; 00049 00050 typedef Signal2<void, SocketServer *, const Socket &> 00051 SocketServerSignalSocket; 00052 00053 /** 00054 * @brief An exception class to hold Socket related errors. 00055 * 00056 * scim::Socket and its derived classes must throw 00057 * scim::SocketError object when error. 00058 */ 00059 class SocketError: public Exception 00060 { 00061 public: 00062 SocketError (const String& what_arg) 00063 : Exception (String("scim::Socket: ") + what_arg) { } 00064 }; 00065 00066 /** 00067 * @brief The vaild socket address/protocol family, 00068 * 00069 * Corresponding to libc PF_LOCAL/AF_LOCAL and PF_INET/AF_INET 00070 */ 00071 enum SocketFamily 00072 { 00073 SCIM_SOCKET_UNKNOWN, /**< Unknown or invalid socket address/protocol */ 00074 SCIM_SOCKET_LOCAL, /**< Unix local socket address/protocol */ 00075 SCIM_SOCKET_INET /**< Internet (ipv4) socket address/protocol */ 00076 }; 00077 00078 /** 00079 * @brief The class to hold a socket address. 00080 * 00081 * Class SocketAddress encapsulates the details of 00082 * socket address, like socketaddr_un and socketaddr_in. 00083 * 00084 * A SocketAddress object can be constructed from an 00085 * address string, which must start with one of the 00086 * following prefixes: 00087 * - inet: or tcp: 00088 * A internet address (ipv4). This kind of address must 00089 * include two parts, separated by a colon. The first part 00090 * is the ip address, the second part is the port. For example: 00091 * inet:127.0.0.1:12345 00092 * - local: or unix: or file: 00093 * A unix or local socket address. It's a full path of a socket file. 00094 * For example: local:/tmp/scim-socket-frontend 00095 */ 00096 class SocketAddress 00097 { 00098 class SocketAddressImpl; 00099 SocketAddressImpl *m_impl; 00100 00101 public: 00102 /** 00103 * @brief Constructor. 00104 * 00105 * @param addr the address string. 00106 */ 00107 SocketAddress (const String &addr = String ()); 00108 00109 /** 00110 * @brief Copy constructor. 00111 */ 00112 SocketAddress (const SocketAddress &addr); 00113 00114 /** 00115 * @brief Destructor. 00116 */ 00117 ~SocketAddress (); 00118 00119 /** 00120 * @brief Copy operator. 00121 */ 00122 const SocketAddress& operator = (const SocketAddress &addr); 00123 00124 /** 00125 * @brief Check if this address is valid. 00126 * 00127 * @return true if this address is valid. 00128 */ 00129 bool valid () const; 00130 00131 /** 00132 * @brief Get the family of this socket address. 00133 * 00134 * @return the family enum value of this address. 00135 * 00136 * @sa SocketFamily 00137 */ 00138 SocketFamily get_family () const; 00139 00140 /** 00141 * @brief Set a new address. 00142 * 00143 * @param addr the new address string. 00144 */ 00145 bool set_address (const String &addr); 00146 00147 /** 00148 * @brief Get the address string. 00149 * 00150 * @return the address string. 00151 */ 00152 String get_address () const; 00153 00154 /** 00155 * @brief Get the internal data of this socket address, 00156 * used by class Socket. 00157 * 00158 * @return the pointer to the data, usually a sockaddr struct. 00159 */ 00160 const void * get_data () const; 00161 00162 /** 00163 * @brief Get the size of the internall data. 00164 * 00165 * @return the size of the internall data returned by get_data (); 00166 */ 00167 int get_data_length () const; 00168 }; 00169 00170 /** 00171 * @brief Socket communication class. 00172 * 00173 * Class Socket provides basic operation of socket, 00174 * such as bind connect, read, write etc. 00175 * 00176 * This class object cannot be created directly by user. 00177 * Only the object of its derived classes SocketServer and SocketClient 00178 * can be created directly. 00179 */ 00180 class Socket 00181 { 00182 class SocketImpl; 00183 00184 SocketImpl *m_impl; 00185 00186 Socket (const Socket&); 00187 const Socket& operator = (const Socket&); 00188 00189 public: 00190 /** 00191 * @brief Create a Socket object from an already created socket_id. 00192 * 00193 * @param id an file id of an existing socket. 00194 */ 00195 Socket (int id = -1); 00196 00197 /** 00198 * @brief Destructor 00199 */ 00200 ~Socket (); 00201 00202 /** 00203 * @brief Check if the socket is valid. 00204 * 00205 * @return true if the socket is ready to read and write. 00206 */ 00207 bool valid () const; 00208 00209 /** 00210 * @brief Read data from socket. 00211 * 00212 * @param buf the buffer to store the data. 00213 * @param size size of the buffer. 00214 * 00215 * @return the amount of data actually read, -1 means error occurred. 00216 */ 00217 int read (void *buf, size_t size) const; 00218 00219 /** 00220 * @brief read data from socket with a timeout. 00221 * 00222 * @param buf the buffer to store the data. 00223 * @param size size of the buffer, and the amount of data to be read. 00224 * @param timeout time out in millisecond (1/1000 second), -1 means infinity. 00225 * 00226 * @return the amount of data actually read, 00227 * 0 means the connection is closed, 00228 * -1 means error occurred. 00229 */ 00230 int read_with_timeout (void *buf, size_t size, int timeout) const; 00231 00232 /** 00233 * @brief Write data to socket. 00234 * 00235 * @param buf the buffer stores the data. 00236 * @param size size of the data to be sent. 00237 * 00238 * @return the amount of data acutally sent, or -1 if an error occurred. 00239 */ 00240 int write (const void *buf, size_t size) const; 00241 00242 /** 00243 * @brief Wait until there are some data ready to read. 00244 * 00245 * @param timeout time out in millisecond (1/1000 second), -1 means infinity. 00246 * 00247 * @return > 0 if data is OK, == 0 if time is out, < 0 if an error occurred. 00248 */ 00249 int wait_for_data (int timeout = -1) const; 00250 00251 /** 00252 * @brief Get the number of the last occurred error. 00253 * 00254 * @return the standard errno value. 00255 */ 00256 int get_error_number () const; 00257 00258 /** 00259 * @brief Get the message of the last occurred error. 00260 * 00261 * @return the error message of the last occurred error. 00262 */ 00263 String get_error_message () const; 00264 00265 /** 00266 * @brief Get the socket id. 00267 * 00268 * @return the file id of this socket object. 00269 */ 00270 int get_id () const; 00271 00272 protected: 00273 00274 /** 00275 * @brief Initiate a connection on a socket. 00276 * 00277 * @param addr the address to be connected to. 00278 * 00279 * @return true if success. 00280 */ 00281 bool connect (const SocketAddress &addr) const; 00282 00283 /** 00284 * @brief Bind a socket to an address, used by SocketServer. 00285 * 00286 * @param addr the address to be binded to. 00287 * 00288 * @return true if success. 00289 */ 00290 bool bind (const SocketAddress &addr) const; 00291 00292 /** 00293 * @brief Listen for connections on a socket. 00294 * 00295 * @param queue_length the length of the waiting queue. 00296 * 00297 * @return true if success. 00298 */ 00299 bool listen (int queue_length = 5) const; 00300 00301 /** 00302 * @brief Accept a connection on the socket, used by SocketServer. 00303 * 00304 * @return the id of the accepted client socket, or -1 if an error is occurred. 00305 */ 00306 int accept () const; 00307 00308 /** 00309 * @brief Create a socket for specific family. 00310 * 00311 * @param family the family type. 00312 * 00313 * @return true if success. 00314 */ 00315 bool create (SocketFamily family); 00316 00317 /** 00318 * @brief Close the socket. 00319 */ 00320 void close (); 00321 }; 00322 00323 /** 00324 * @brief Socket Server class. 00325 * 00326 * Class SocketServer provides basic operations to create a Socket Server, 00327 * such as create, run etc. 00328 */ 00329 class SocketServer : private Socket 00330 { 00331 class SocketServerImpl; 00332 00333 SocketServerImpl *m_impl; 00334 00335 public: 00336 /** 00337 * @brief Default constructor, do nothing. 00338 */ 00339 SocketServer (int max_clients = -1); 00340 00341 /** 00342 * @brief Constructor. 00343 * 00344 * @param address create a server on this address. 00345 * @param max_clients the max number of socket clients, -1 means unlimited. 00346 */ 00347 SocketServer (const SocketAddress &address, int max_clients = -1); 00348 00349 /** 00350 * @brief Destructor. 00351 */ 00352 ~SocketServer (); 00353 00354 /** 00355 * @brief Test if the server is valid. 00356 * 00357 * @return true if the socket server is valid and ready to run. 00358 */ 00359 bool valid (); 00360 00361 /** 00362 * @brief Create a socket on an address. 00363 * 00364 * @param address the address to be listen. 00365 * 00366 * @return true if OK. 00367 */ 00368 bool create (const SocketAddress &address); 00369 00370 /** 00371 * @brief Run the server. 00372 * 00373 * @return true if it ran successfully. 00374 */ 00375 bool run (); 00376 00377 /** 00378 * @brief Check if the server is running. 00379 * 00380 * @return true if it's running. 00381 */ 00382 bool is_running () const; 00383 00384 /** 00385 * @brief Shutdown the server. 00386 */ 00387 void shutdown (); 00388 00389 /** 00390 * @brief Close a client connection. 00391 * 00392 * @param socket the client socket object to be closed. 00393 */ 00394 void close_connection (const Socket &socket); 00395 00396 /** 00397 * @brief Get the number of the last occurred error. 00398 * 00399 * @return the standard errno value. 00400 */ 00401 int get_error_number () const; 00402 00403 /** 00404 * @brief Get the message of the last occurred error. 00405 * 00406 * @return the error message corresponding to the errno. 00407 */ 00408 String get_error_message () const; 00409 00410 /** 00411 * @brief Get the max number of socket clients. 00412 * 00413 * @return the max number of socket clients allowed to connect this server. 00414 */ 00415 int get_max_clients () const; 00416 00417 /** 00418 * @brief Set the max number of clients. 00419 * 00420 * @param max_clients the max number of socket clients allowed to connect this server. 00421 */ 00422 void set_max_clients (int max_clients); 00423 00424 public: 00425 /** 00426 * @brief Connect a slot to socket accept signal. 00427 * 00428 * Connect a slot to socket accept signal, if a client connection is accepted, 00429 * this signal will be emitted. 00430 * 00431 * @param slot the slot to be connected to this signal. 00432 * 00433 * @return the Connection object of this slot-signal connection, can be used 00434 * to disconnect the slot later. 00435 */ 00436 Connection signal_connect_accept (SocketServerSlotSocket *slot); 00437 00438 /** 00439 * @brief Connect a slot to socket receive signal. 00440 * 00441 * Connect a slot to socket receive signal, if a client send data to this server, 00442 * this signal will be emitted. 00443 * 00444 * @param slot the slot to be connected to this signal. 00445 * 00446 * @return the Connection object of this slot-signal connection, can be used 00447 * to disconnect the slot later. 00448 */ 00449 Connection signal_connect_receive (SocketServerSlotSocket *slot); 00450 00451 /** 00452 * @brief Connect a slot to socket exception signal. 00453 * 00454 * Connect a slot to socket exception signal, if an exception was occurred 00455 * to a client connection, this signal will be emitted. 00456 * 00457 * @param slot the slot to be connected to this signal. 00458 * 00459 * @return the Connection object of this slot-signal connection, can be used 00460 * to disconnect the slot later. 00461 */ 00462 Connection signal_connect_exception (SocketServerSlotSocket *slot); 00463 }; 00464 00465 /** 00466 * @brief Socket client class. 00467 * 00468 * Class SocketClient provides basic operations to create a Socket Client, 00469 * such as connect, read, write, etc. 00470 */ 00471 class SocketClient : public Socket 00472 { 00473 bool m_connected; 00474 00475 public: 00476 /** 00477 * @brief Constructor. 00478 */ 00479 SocketClient (); 00480 00481 /** 00482 * @brief Constructor. 00483 * 00484 * @param address the server address to be connected. 00485 */ 00486 SocketClient (const SocketAddress &address); 00487 00488 /** 00489 * @brief Destructor. 00490 */ 00491 ~SocketClient (); 00492 00493 /** 00494 * @brief Check if the socket is connected. 00495 * 00496 * @return true if the socket client is connected to a server. 00497 */ 00498 bool is_connected () const; 00499 00500 /** 00501 * @brief Connect to a server. 00502 * 00503 * @param address the server socket address to be connected to. 00504 * 00505 * @return true if connected successfully. 00506 */ 00507 bool connect (const SocketAddress &address); 00508 00509 /** 00510 * @brief Close the client. 00511 */ 00512 void close (); 00513 }; 00514 00515 /** 00516 * @brief Get the default socket address of SocketFrontEnd 00517 * 00518 * SocketFrontEnd should listen on this address by default. 00519 */ 00520 String scim_get_default_socket_frontend_address (); 00521 00522 /** 00523 * @brief Get the default socket address of SocketIMEngine 00524 * 00525 * SocketIMEngine should connect to this address by default. 00526 */ 00527 String scim_get_default_socket_imengine_address (); 00528 00529 /** 00530 * @brief Get the default socket address of SocketConfig 00531 * 00532 * SocketConfig should connect to this address by default. 00533 */ 00534 String scim_get_default_socket_config_address (); 00535 00536 /** 00537 * @brief Get the default socket address of the Panel running on localhost. 00538 * 00539 * The panel running on local host should listen on this address by default. 00540 * All FrontEnds which need panel should connect to this address by default. 00541 */ 00542 String scim_get_default_panel_socket_address (); 00543 00544 /** 00545 * @brief Get the default socket timeout value. 00546 * 00547 * All socket connection should use this timeout value. 00548 */ 00549 int scim_get_default_socket_timeout (); 00550 00551 /** @} */ 00552 00553 } // namespace scim 00554 00555 #endif //__SCIM_SOCKET_H 00556 00557 /* 00558 vi:ts=4:nowrap:ai:expandtab 00559 */ 00560