Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

Socket.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 dEVICE cOMMUNITIES dEVELOPMENT tOOLKIT 
00003 
00004 DCDT_Socket.h
00005 
00006 COPYRIGHT (C) 2002   Alessandro Mazzini (mazzini@airlab.elet.polimi.it)
00007 
00008 
00009 This library is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU Lesser General Public
00011 License as published by the Free Software Foundation; either
00012 version 2 of the License, or (at your option) any later version.
00013 
00014 This library is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public
00020 License along with this library; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
00022 
00023 ****************************************************************************/
00024 
00025 #ifndef SOCKET_H
00026 #define SOCKET_H
00027 
00028 #include <unistd.h>
00029 #include <netinet/in.h>
00030 #include <arpa/inet.h>
00031 #include <string.h>
00032 #include <sys/socket.h>
00033 #include <errno.h>
00034 #include <stdlib.h>
00035 #include <DCDT_Defs.h>
00036 #include <DCDT_Msg.h>
00037 
00044 class Socket
00045 {
00046 public:
00047   Socket()
00048   {
00049     sockfd = opened = bound = connected = tconn_flag = tlost_flag = tsend_flag = trecv_flag = 0;
00050     tconn_value.tv_sec = tconn_value.tv_usec = tlost_value.tv_sec = tlost_value.tv_usec = 0;
00051     tsend_value.tv_sec = tsend_value.tv_usec = trecv_value.tv_sec = trecv_value.tv_usec = 0;
00052     unblock_send_flag = unblock_recv_flag = 0;
00053   };
00054   virtual ~Socket() {};
00055 
00056   virtual void Open(int fd = 0) = 0;
00057   inline void Bind(int addr, short port);
00058   inline void Connect(int addr, short port);
00059   virtual void Send(const DCDT_Msg *msg) = 0;
00060   virtual DCDT_Msg* Receive() = 0;
00061   inline void Close();
00062   inline void ForcedClose();
00063   inline void GetOption(int level, int optname);
00064   inline void SetOption(int level, int optname);
00065   inline void UnSetOption(int level, int optname);
00066   inline void GetName(char *addr, short &port);
00067   inline void GetCommData(int &addr, short &port);
00068   inline void SetLostTimer(int usec);
00069   inline void LostTimerOn();
00070   inline void LostTimerOff();
00071   inline void SetConnTimer(int usec);
00072   inline void ConnTimerOn();
00073   inline void ConnTimerOff();
00074   inline void SetSendTimer(int usec);
00075   inline void SendTimerOn();
00076   inline void SendTimerOff();
00077   inline void UnblockSend();
00078   inline void SetReceiveTimer(int usec);
00079   inline void ReceiveTimerOn();
00080   inline void ReceiveTimerOff();
00081   inline void UnblockReceive();
00082   int GetFd() { return sockfd; };
00083 
00084 protected:
00085   int sockfd,
00087     opened,
00089     bound, 
00091     connected,
00093     tconn_flag,
00095     tlost_flag, 
00097     tsend_flag,
00099     trecv_flag;
00100   int
00102     unblock_send_flag,
00104     unblock_recv_flag;
00105   struct timeval tconn_value, tlost_value, tsend_value, trecv_value;
00106   int my_addr;
00107   short my_port;
00108 
00109 };
00110 
00116 inline void Socket::Bind(int addr, short port)
00117 {
00118   struct sockaddr_in bindaddr;
00119   if (!opened || bound)
00120     return;
00121 
00122   bindaddr.sin_family = AF_INET;
00123   if (!addr)
00124     bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
00125   else {
00126     bindaddr.sin_addr.s_addr = (in_addr_t)addr;
00127     my_addr = (int)bindaddr.sin_addr.s_addr;
00128   }
00129   bindaddr.sin_port = my_port = port;
00130 
00131   if (bind(sockfd, (struct sockaddr*) &bindaddr, sizeof(bindaddr)) < 0)
00132     throw ChannelError(errno);
00133 
00134   TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket successfully bound to: %i port: %i", addr, port));
00135 
00136   bound = 1;
00137 }
00138 
00144 inline void Socket::Connect(int addr, short port)
00145 {
00146   struct sockaddr_in connaddr;
00147 
00148   if (!opened || connected)
00149     return;
00150 
00151   connaddr.sin_family = AF_INET;
00152   connaddr.sin_addr.s_addr = (in_addr_t)addr;
00153   connaddr.sin_port = port;
00154 
00155   if (connect(sockfd, (struct sockaddr *) &connaddr, sizeof(connaddr)) < 0)
00156     throw ConnError(errno);
00157 
00158   TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket successfully connected to: %i port: %i", addr, port));
00159   connected = 1;
00160 }
00161 
00163 inline void Socket::Close()
00164 {
00165   if (opened) {
00166     if (close(sockfd) < 0)
00167       throw ConnError(errno);
00168     connected = opened = bound = sockfd = 0;
00169 
00170     TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket successfully closed"));
00171   }
00172 }
00173 
00174 inline void Socket::ForcedClose()
00175 {
00176   if (opened) {
00177     shutdown(sockfd, SHUT_RDWR);
00178     connected = opened = bound = sockfd = 0;
00179     
00180     TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket successfully shut"));
00181   }
00182 }
00183 
00184 
00186 inline void Socket::GetOption(int level, int optname)
00187 {
00188   int val;
00189   socklen_t sl = sizeof(val);
00190 
00191   if (!opened)
00192     return;
00193   if (getsockopt(sockfd, level, optname, &val, &sl) < 0)
00194     throw ChannelError(errno);
00195 
00196   TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket option value: %i", val));
00197 }
00198 
00200 inline void Socket::SetOption(int level, int optname)
00201 {
00202   int val = 1;
00203 
00204   if (!opened)
00205     return;
00206   if (setsockopt(sockfd, level, optname, &val, sizeof(val)) < 0)
00207     throw ChannelError(errno);
00208 
00209   TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket option successfully set"));
00210 }
00211 
00213 inline void Socket::UnSetOption(int level, int optname)
00214 {
00215   int val = 0;
00216 
00217   if (!opened)
00218     throw ChannelError();
00219   if (setsockopt(sockfd, level, optname, &val, sizeof(val)) < 0)
00220     throw ChannelError(errno);
00221 
00222   TRC_PRINT( DCDT_TRC_COMM, TRC1, ("Socket option successfully unset"));
00223 }
00224 
00226 inline void Socket::GetName(char *addr, short &port)
00227 {
00228   struct sockaddr_in sa;
00229   socklen_t sl = sizeof(sa);
00230   char localaddr[INET_ADDRSTRLEN];
00231   
00232   if (getsockname(sockfd, (struct sockaddr*) &sa, &sl) < 0 \
00233       || !inet_ntop(sa.sin_family, &sa.sin_addr, localaddr, INET_ADDRSTRLEN))
00234     throw ChannelError(errno);
00235   if (addr)
00236     strcpy(addr, localaddr);
00237   port = sa.sin_port;
00238   
00239 }
00240 
00242 inline void Socket::GetCommData(int &addr, short &port)
00243 {
00244   struct sockaddr_in sa;
00245   socklen_t sl = sizeof(sa);
00246 
00247   if (getsockname(sockfd, (struct sockaddr*) &sa, &sl) < 0)
00248     throw ChannelError(errno);
00249   if ((int)sa.sin_addr.s_addr == 0)
00250     addr = my_addr;
00251   else
00252     addr = (int)sa.sin_addr.s_addr;
00253   port = sa.sin_port;
00254 
00255 }
00256 
00257 inline void Socket::SetLostTimer(int usec)
00258 {
00259   tlost_value.tv_usec = usec % 1000000;
00260   tlost_value.tv_sec = usec / 1000000;
00261 };
00262 
00263 inline void Socket::LostTimerOn()
00264 {
00265   tlost_flag = 1;
00266 };
00267 
00268 inline void Socket::LostTimerOff()
00269 {
00270   tlost_flag = 0;
00271 };
00272 
00273 inline void Socket::SetConnTimer(int usec)
00274 {
00275   tconn_value.tv_usec = usec % 1000000;
00276   tconn_value.tv_sec = usec / 1000000;
00277 };
00278 
00279 inline void Socket::ConnTimerOn()
00280 {
00281   tconn_flag = 1;
00282 };
00283 
00284 inline void Socket::ConnTimerOff()
00285 {
00286   tconn_flag = 0;
00287 };
00288 
00289 inline void Socket::SetSendTimer(int usec)
00290 {
00291   tsend_value.tv_usec = usec % 1000000;
00292   tsend_value.tv_sec = usec / 1000000;
00293 };
00294 
00295 inline void Socket::SendTimerOn()
00296 {
00297   tsend_flag = 1;
00298   unblock_send_flag = 0;
00299 };
00300 
00301 inline void Socket::SendTimerOff()
00302 {
00303   tsend_flag = 0;
00304 };
00305 
00306 inline void Socket::UnblockSend()
00307 {
00308   unblock_send_flag = 1;
00309 }
00310 
00311 inline void Socket::SetReceiveTimer(int usec)
00312 {
00313   trecv_value.tv_usec = usec % 1000000;
00314   trecv_value.tv_sec = usec / 1000000;
00315 };
00316 
00317 inline void Socket::ReceiveTimerOn()
00318 {
00319   trecv_flag = 1;
00320   unblock_recv_flag = 0;
00321 };
00322 
00323 inline void Socket::ReceiveTimerOff()
00324 {
00325   trecv_flag = 0;
00326 };
00327 
00328 inline void Socket::UnblockReceive()
00329 {
00330   unblock_recv_flag = 1;
00331 }
00332 
00333 #endif
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 

Generated on Sun Jun 19 10:35:50 2005 for dcdt by  doxygen 1.3.9.1