00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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);
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);
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