Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

SockOp.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Socket I/O operations
00004     Copyright (C) 1999-2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026 #include <fcntl.h>
00027 #include <errno.h>
00028 #include <sys/types.h>
00029 #include <sys/socket.h>
00030 #include <sys/time.h>
00031 #include <netinet/in.h>
00032 #include <netinet/ip.h>
00033 #include <netinet/tcp.h>
00034 
00035 #include "SockOp.hh"
00036 
00037 
00038 clSockOp::clSockOp()
00039 {
00040     bCloseOnDestruct = true;
00041     iSockH = -1;
00042 }
00043 
00044 
00045 clSockOp::clSockOp(int iHandle)
00046 {
00047     bCloseOnDestruct = true;
00048     iSockH = iHandle;
00049 }
00050 
00051 
00052 clSockOp::~clSockOp()
00053 {
00054     if (bCloseOnDestruct && (iSockH >= 0)) close(iSockH);
00055 }
00056 
00057 
00058 void clSockOp::SetHandle(int iHandle)
00059 {
00060     if (iSockH >= 0) Close();
00061     iSockH = iHandle;
00062 }
00063 
00064 
00065 void clSockOp::Close()
00066 {
00067     if (iSockH >= 0) 
00068     {
00069         close(iSockH);
00070         iSockH = -1;
00071     }
00072 }
00073 
00074 
00075 bool clSockOp::ReadSelect(int iTimeoutMS)
00076 {
00077     int iSelectRes;
00078     struct timeval sTimeout;
00079     fd_set fdsetSelect;
00080 
00081     sTimeout.tv_sec = iTimeoutMS / 1000;
00082     sTimeout.tv_usec = iTimeoutMS % 1000 * 1000;
00083     FD_ZERO(&fdsetSelect);
00084     FD_SET(iSockH, &fdsetSelect);
00085     iSelectRes = select(iSockH + 1, &fdsetSelect, NULL, NULL, &sTimeout);
00086     if (iSelectRes == 0)
00087     {
00088         iErrno = 0;
00089         return false;
00090     }
00091     else if (iSelectRes < 0)
00092     {
00093         iErrno = errno;
00094         return false;
00095     }
00096     return true;
00097 }
00098 
00099 
00100 bool clSockOp::WriteSelect(int iTimeoutMS)
00101 {
00102     int iSelectRes;
00103     struct timeval sTimeout;
00104     fd_set fdsetSelect;
00105 
00106     sTimeout.tv_sec = iTimeoutMS / 1000;
00107     sTimeout.tv_usec = iTimeoutMS % 1000 * 1000;
00108     FD_ZERO(&fdsetSelect);
00109     FD_SET(iSockH, &fdsetSelect);
00110     iSelectRes = select(iSockH + 1, NULL, &fdsetSelect, NULL, &sTimeout);
00111     if (iSelectRes == 0)
00112     {
00113         iErrno = 0;
00114         return false;
00115     }
00116     else if (iSelectRes < 0)
00117     {
00118         iErrno = errno;
00119         return false;
00120     }
00121     return true;
00122 }
00123 
00124 
00125 int clSockOp::Read(void *vpBuf, int iBufLen)
00126 {
00127     iRetVal = read(iSockH, vpBuf, iBufLen);
00128     iErrno = errno;
00129     return iRetVal;
00130 }
00131 
00132 
00133 int clSockOp::Write(const void *vpBuf, int iBufLen)
00134 {
00135     iRetVal = write(iSockH, vpBuf, iBufLen);
00136     iErrno = errno;
00137     return iRetVal;
00138 }
00139 
00140 
00141 int clSockOp::ReadN(void *vpBuf, int iBufLen)
00142 {
00143     int iBytesRead = 0;
00144     char *cpBufPtr = (char *) vpBuf;
00145 
00146     do {
00147 #       ifndef LINUXSYS
00148         iRetVal = recv(iSockH, &cpBufPtr[iBytesRead], iBufLen - iBytesRead, 0);
00149 #       else
00150         iRetVal = recv(iSockH, &cpBufPtr[iBytesRead], iBufLen - iBytesRead,
00151             MSG_NOSIGNAL);
00152 #       endif
00153         iBytesRead += iRetVal;
00154     } while (iBytesRead < iBufLen && iRetVal > 0);  // was iRetVal >= 0
00155     iErrno = errno;
00156     return iBytesRead;
00157 }
00158 
00159 
00160 int clSockOp::WriteN(const void *vpBuf, int iBufLen)
00161 {
00162     int iBytesWritten = 0;
00163     char *cpBufPtr = (char *) vpBuf;
00164 
00165     do {
00166 #       ifndef LINUXSYS
00167         iRetVal = send(iSockH, &cpBufPtr[iBytesWritten], 
00168             iBufLen - iBytesWritten, 0);
00169 #       else
00170         iRetVal = send(iSockH, &cpBufPtr[iBytesWritten], 
00171             iBufLen - iBytesWritten, MSG_NOSIGNAL);
00172 #       endif
00173         iBytesWritten += iRetVal;
00174     } while (iBytesWritten < iBufLen && iRetVal > 0);  // was iRetVal >= 0
00175     iErrno = errno;
00176     return iBytesWritten;
00177 }
00178 
00179 
00180 int clSockOp::Receive(void *vpBuf, int iBufLen, int iFlags)
00181 {
00182     iRetVal = recv(iSockH, vpBuf, iBufLen, iFlags);
00183     iErrno = errno;
00184     return iRetVal;
00185 }
00186 
00187 
00188 int clSockOp::Send(const void *vpBuf, int iBufLen, int iFlags)
00189 {
00190     iRetVal = send(iSockH, vpBuf, iBufLen, iFlags);
00191     iErrno = errno;
00192     return iRetVal;
00193 }
00194 
00195 
00196 int clSockOp::ReceiveMsg(struct msghdr *sMsgHdr, int iFlags)
00197 {
00198     iRetVal = recvmsg(iSockH, sMsgHdr, iFlags);
00199     iErrno = errno;
00200     return iRetVal;
00201 }
00202 
00203 
00204 int clSockOp::SendMsg(const struct msghdr *sMsgHdr, int iFlags)
00205 {
00206     iRetVal = sendmsg(iSockH, sMsgHdr, iFlags);
00207     iErrno = errno;
00208     return iRetVal;
00209 }
00210 
00211 
00212 int clSockOp::Shutdown(int iShutdownDir)
00213 {
00214     iRetVal = shutdown(iSockH, iShutdownDir);
00215     iErrno = errno;
00216     return iRetVal;
00217 }
00218 
00219 
00220 int clSockOp::GetSockName(struct sockaddr *spAddr, socklen_t *ipAddrLen)
00221 {
00222     iRetVal = getsockname(iSockH, spAddr, ipAddrLen);
00223     iErrno = errno;
00224     return iRetVal;
00225 }
00226 
00227 
00228 int clSockOp::GetPeerName(struct sockaddr *spAddr, socklen_t *ipAddrLen)
00229 {
00230     iRetVal = getpeername(iSockH, spAddr, ipAddrLen);
00231     iErrno = errno;
00232     return iRetVal;
00233 }
00234 
00235 
00236 bool clSockOp::SetBlocking(bool bBlocking)
00237 {
00238     int iMode;
00239 
00240     iMode = fcntl(iSockH, F_GETFL);
00241     if (iMode < 0)
00242     {
00243         iErrno = errno;
00244         return false;
00245     }
00246     if (bBlocking)
00247     {
00248         iMode &= ~(O_NONBLOCK);
00249     }
00250     else
00251     {
00252         iMode |= O_NONBLOCK;
00253     }
00254     if (fcntl(iSockH, F_SETFL, iMode) < 0)
00255     {
00256         iErrno = errno;
00257         return false;
00258     }
00259     return true;
00260 }
00261 
00262 
00263 bool clSockOp::SetKeepAlive()
00264 {
00265     int iFlag = 1;
00266     
00267     if (setsockopt(iSockH, SOL_SOCKET, SO_KEEPALIVE, &iFlag, 
00268         sizeof(iFlag)) < 0)
00269     {
00270         iErrno = errno;
00271         return false;
00272     }
00273     return true;
00274 }
00275 
00276 
00277 bool clSockOp::SetLinger(int iLingerTime)
00278 {
00279     struct linger sLinger;
00280 
00281     sLinger.l_onoff = 1;
00282     sLinger.l_linger = iLingerTime;
00283     if (setsockopt(iSockH, SOL_SOCKET, SO_LINGER, &sLinger, 
00284         sizeof(sLinger)) < 0)
00285     {
00286         iErrno = errno;
00287         return false;
00288     }
00289     return true;
00290 }
00291 
00292 
00293 int clSockOp::GetRecvBufSize()
00294 {
00295     int iRecvBufSize;
00296     socklen_t iValSize;
00297 
00298     iValSize = sizeof(iRecvBufSize);
00299     if (getsockopt(iSockH, SOL_SOCKET, SO_RCVBUF, &iRecvBufSize, 
00300         &iValSize) < 0)
00301     {
00302         iErrno = errno;
00303         return -1;
00304     }
00305     return iRecvBufSize;
00306 }
00307 
00308 
00309 bool clSockOp::SetRecvBufSize(int iBufSize)
00310 {
00311     if (setsockopt(iSockH, SOL_SOCKET, SO_RCVBUF, &iBufSize, 
00312         sizeof(iBufSize)) < 0)
00313     {
00314         iErrno = errno;
00315         return false;
00316     }
00317     return true;
00318 }
00319 
00320 
00321 int clSockOp::GetSendBufSize()
00322 {
00323     int iSendBufSize;
00324     socklen_t iValSize;
00325 
00326     iValSize = sizeof(iSendBufSize);
00327     if (getsockopt(iSockH, SOL_SOCKET, SO_SNDBUF, &iSendBufSize, 
00328         &iValSize) < 0)
00329     {
00330         iErrno = errno;
00331         return -1;
00332     }
00333     return iSendBufSize;
00334 }
00335 
00336 
00337 bool clSockOp::SetSendBufSize(int iBufSize)
00338 {
00339     if (setsockopt(iSockH, SOL_SOCKET, SO_SNDBUF, &iBufSize,
00340         sizeof(iBufSize)) < 0)
00341     {
00342         iErrno = errno;
00343         return false;
00344     }
00345     return true;
00346 }
00347 
00348 
00349 int clSockOp::GetRecvBufLowWater()
00350 {
00351     int iBufLowWater;
00352     socklen_t iValSize;
00353 
00354     iValSize = sizeof(iBufLowWater);
00355     if (getsockopt(iSockH, SOL_SOCKET, SO_RCVLOWAT, &iBufLowWater,
00356         &iValSize) < 0)
00357     {
00358         iErrno = errno;
00359         return -1;
00360     }
00361     return iBufLowWater;
00362 }
00363 
00364 
00365 bool clSockOp::SetRecvBufLowWater(int iBufLowWater)
00366 {
00367     if (setsockopt(iSockH, SOL_SOCKET, SO_RCVLOWAT, &iBufLowWater,
00368         sizeof(iBufLowWater)) < 0)
00369     {
00370         iErrno = errno;
00371         return false;
00372     }
00373     return true;
00374 }
00375 
00376 
00377 int clSockOp::GetSendBufLowWater()
00378 {
00379     int iBufLowWater;
00380     socklen_t iValSize;
00381 
00382     iValSize = sizeof(iBufLowWater);
00383     if (getsockopt(iSockH, SOL_SOCKET, SO_SNDLOWAT, &iBufLowWater,
00384         &iValSize) < 0)
00385     {
00386         iErrno = errno;
00387         return -1;
00388     }
00389     return iBufLowWater;
00390 }
00391 
00392 
00393 bool clSockOp::SetSendBufLowWater(int iBufLowWater)
00394 {
00395     if (setsockopt(iSockH, SOL_SOCKET, SO_SNDLOWAT, &iBufLowWater,
00396         sizeof(iBufLowWater)) < 0)
00397     {
00398         iErrno = errno;
00399         return false;
00400     }
00401     return true;
00402 }
00403 
00404 
00405 bool clSockOp::SetRecvTimeout(int iTimeoutMS)
00406 {
00407     struct timeval sTimeout;
00408 
00409     sTimeout.tv_sec = iTimeoutMS / 1000;
00410     sTimeout.tv_usec = iTimeoutMS % 1000 * 1000;
00411     if (setsockopt(iSockH, SOL_SOCKET, SO_RCVTIMEO, &sTimeout,
00412         sizeof(sTimeout)) < 0)
00413     {
00414         iErrno = errno;
00415         return false;
00416     }
00417     return true;
00418 }
00419 
00420 
00421 bool clSockOp::SetSendTimeout(int iTimeoutMS)
00422 {
00423     struct timeval sTimeout;
00424 
00425     sTimeout.tv_sec = iTimeoutMS / 1000;
00426     sTimeout.tv_usec = iTimeoutMS % 1000 * 1000;
00427     if (setsockopt(iSockH, SOL_SOCKET, SO_SNDTIMEO, &sTimeout,
00428         sizeof(sTimeout)) < 0)
00429     {
00430         iErrno = errno;
00431         return false;
00432     }
00433     return true;
00434 }
00435 
00436 
00437 bool clSockOp::SetTCPKeepAlive(int iTimeSec)
00438 {
00439     #ifdef HAVE_TCP_KEEPALIVE
00440     if (setsockopt(iSockH, IPPROTO_TCP, TCP_KEEPALIVE, &iTimeSec,
00441         sizeof(iTimeSec)) < 0)
00442     {
00443         iErrno = errno;
00444         return false;
00445     }
00446     #endif
00447     return true;
00448 }
00449 
00450 
00451 bool clSockOp::DisableNagle()
00452 {
00453     int iFlag = 1;
00454     
00455     if (setsockopt(iSockH, IPPROTO_TCP, TCP_NODELAY, &iFlag, 
00456         sizeof(iFlag)) < 0)
00457     {
00458         iErrno = errno;
00459         return false;
00460     }
00461     return true;
00462 }
00463 
00464 
00465 bool clSockOp::SetNagle(bool bNagle)
00466 {
00467     int iFlag = (bNagle) ? 0 : 1;
00468     
00469     if (setsockopt(iSockH, IPPROTO_TCP, TCP_NODELAY, &iFlag,
00470         sizeof(iFlag)) < 0)
00471     {
00472         iErrno = errno;
00473         return false;
00474     }
00475     return true;
00476 }
00477 
00478 
00479 bool clSockOp::SetTypeOfService(int iTOS)
00480 {
00481     if (setsockopt(iSockH, IPPROTO_IP, IP_TOS, &iTOS,
00482         sizeof(iTOS)) < 0)
00483     {
00484         iErrno = errno;
00485         return false;
00486     }
00487     return true;
00488 }
00489 
00490 
00491 void clSockOp::SetCloseOnDestruct(bool bSetting)
00492 {
00493     bCloseOnDestruct = bSetting;
00494 }
00495 

Generated on Sun Oct 26 19:11:22 2003 for HASAS by doxygen 1.3.3