#include "cdevSocketStream.h" // ***************************************************************************** // * cdevSocketStream::cdevSocketStream : // * Constructor for the cdevSocketStream class. Only serves to initialize // * the readRetryCount variable. // ***************************************************************************** cdevSocketStream::cdevSocketStream ( void ) { } // ***************************************************************************** // * cdevSocketStream::send : // * Send an n byte message to the connected socket. // ***************************************************************************** ssize_t cdevSocketStream::send(const void *buf, size_t n, int flags) const { int retval; if((retval = ::send(getHandle(), (const char *) buf, n, flags))<=0) { int errCode = GetSocketErrno(); if(errCode==EAGAIN || errCode==EWOULDBLOCK) retval = 0; } return retval; } // ***************************************************************************** // * cdevSocketStream::send_n : // * This method will transmit an n byte message to a connected socket, // * waiting until all data has been transmitted or an error occurs. // ***************************************************************************** ssize_t cdevSocketStream::send_n(const void *buf, size_t n, int flags) const { ssize_t amntsent = 0; int result = 0; while(amntsent<(ssize_t)n && result>=0) { if((result = ::send(getHandle(), (const char *)buf+amntsent, n-amntsent, flags))<=0) { int errCode = GetSocketErrno(); if(errCode==EAGAIN || errCode==EWOULDBLOCK) result = 0; else result = -1; } else amntsent+=result; } return (amntsent>=(ssize_t)n)?amntsent:-1; } // ***************************************************************************** // * cdevSocketStream::recv : // * Recv an n byte message from the connected socket. // ***************************************************************************** ssize_t cdevSocketStream::recv(void *buf, size_t n, int flags) { int retval = 0; if((retval = ::recv(getHandle(), (char *)buf, n, flags))<=0) { int errCode = GetSocketErrno(); if(errCode==EAGAIN || errCode==EWOULDBLOCK) retval = 0; } return retval; } // ***************************************************************************** // * cdevSocketStream::recv_n : // * This method will receive an n byte message from a connected socket, // * waiting until all data has been received or an error occurs. // ***************************************************************************** ssize_t cdevSocketStream::recv_n(void *buf, size_t n, int flags) { ssize_t amntrecv = 0; int result = 0; while(amntrecv < (ssize_t)n) { if((result = ::recv(getHandle(), (char *)buf+amntrecv, n-amntrecv, flags)) < 0) { return -1; } else if (result == 0) break; else amntrecv+=result; } return amntrecv; } // ***************************************************************************** // * cdevSocketStream::closeReader : // * Shut down just the reading end of a cdevSocket. // ***************************************************************************** int cdevSocketStream::closeReader(void) { return ::shutdown(getHandle(), 0); } // ***************************************************************************** // * cdevSocketStream::closeWriter : // * Shut down just the writing end of a cdevSocket. // ***************************************************************************** int cdevSocketStream::closeWriter(void) { return ::shutdown(getHandle(), 1); } int cdevSocketStream::getBlockingSemantics ( void ) const { return O_NONBLOCK; } int cdevSocketStream::getRcvLowWaterMark ( void ) const { return 0; } int cdevSocketStream::getRcvBufferSize ( void ) const { return 56000; } int cdevSocketStream::getSndLowWaterMark ( void ) const { return 16000; } int cdevSocketStream::getSndBufferSize ( void ) const { return 56000; } int cdevSocketStream::configureHandle ( void ) { int retval = 0; int parm = 1; if(getBlockingSemantics()==O_NONBLOCK && setFlags(O_NONBLOCK)==-1) { retval = -1; } setOption(IPPROTO_TCP, TCP_NODELAY, &parm, sizeof(parm)); if((parm = getRcvBufferSize())>0) { setOption(SOL_SOCKET, SO_RCVBUF, &parm, sizeof(parm)); } #ifndef __linux if((parm = getRcvLowWaterMark())>0) { setOption(SOL_SOCKET, SO_RCVLOWAT, &parm, sizeof(parm)); } #endif if((parm = getSndBufferSize())>0) { setOption(SOL_SOCKET, SO_SNDBUF, &parm, sizeof(parm)); } #ifndef __linux if((parm = getSndLowWaterMark())>0) { setOption(SOL_SOCKET, SO_SNDLOWAT, &parm, sizeof(parm)); } #endif return retval; }