From: <ag...@us...> - 2008-10-28 02:37:18
|
Revision: 167 http://zoolib.svn.sourceforge.net/zoolib/?rev=167&view=rev Author: agreen Date: 2008-10-28 02:37:07 +0000 (Tue, 28 Oct 2008) Log Message: ----------- Move the TCP socket stuff to use the new shared socket implementation. Modified Paths: -------------- trunk/zoolib/source/cxx/zoolib/ZNet_Internet.cpp trunk/zoolib/source/cxx/zoolib/ZNet_Internet.h trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.cpp trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.h trunk/zoolib/source/cxx/zoolib/ZNet_Local.cpp trunk/zoolib/source/cxx/zoolib/ZNet_Local.h trunk/zoolib/source/cxx/zoolib/ZNet_Local_Socket.cpp trunk/zoolib/source/cxx/zoolib/ZNet_Socket.cpp Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Internet.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Internet.cpp 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Internet.cpp 2008-10-28 02:37:07 UTC (rev 167) @@ -59,7 +59,7 @@ {} ZRef<ZNetEndpoint> ZNetAddress_Internet::Connect() const - { return ZNetEndpoint_TCP::sCreateConnectedEndpoint(fHost, fPort); } + { return ZNetEndpoint_TCP::sCreateConnected(fHost, fPort); } // ================================================================================================= #pragma mark - @@ -101,6 +101,19 @@ #pragma mark - #pragma mark * ZNetListener_TCP +ZRef<ZNetListener_TCP> ZNetListener_TCP::sCreate(ip_port iPort, size_t iListenQueueSize) + { + return ZFactoryChain_T<ZRef<ZNetListener_TCP>, MakeParam_t> + ::sMake(MakeParam_t(0, iPort, iListenQueueSize)); + } + +ZRef<ZNetListener_TCP> ZNetListener_TCP::sCreate( + ip_addr iAddress, ip_port iPort, size_t iListenQueueSize) + { + return ZFactoryChain_T<ZRef<ZNetListener_TCP>, MakeParam_t> + ::sMake(MakeParam_t(iAddress, iPort, iListenQueueSize)); + } + ZRef<ZNetListener_TCP> ZNetListener_TCP::sCreateListener(ip_port iPort, size_t iListenQueueSize) { return ZFactoryChain_T<ZRef<ZNetListener_TCP>, MakeParam_t> @@ -118,6 +131,13 @@ #pragma mark - #pragma mark * ZNetEndpoint_TCP +ZRef<ZNetEndpoint_TCP> ZNetEndpoint_TCP::sCreateConnected( + ip_addr iRemoteHost, ip_port iRemotePort) + { + return ZFactoryChain_T<ZRef<ZNetEndpoint_TCP>, MakeParam_t> + ::sMake(MakeParam_t(iRemoteHost, iRemotePort)); + } + ZRef<ZNetEndpoint_TCP> ZNetEndpoint_TCP::sCreateConnectedEndpoint( ip_addr iRemoteHost, ip_port iRemotePort) { Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Internet.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Internet.h 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Internet.h 2008-10-28 02:37:07 UTC (rev 167) @@ -96,6 +96,12 @@ virtual ip_port GetPort() = 0; + static ZRef<ZNetListener_TCP> sCreate( + ip_port iPort, size_t iListenQueueSize); + + static ZRef<ZNetListener_TCP> sCreate( + ip_addr iAddress, ip_port iPort, size_t iListenQueueSize); + static ZRef<ZNetListener_TCP> sCreateListener( ip_port iPort, size_t iListenQueueSize); @@ -112,6 +118,9 @@ public: typedef ZMulti_T2<ip_addr, ip_port> MakeParam_t; + static ZRef<ZNetEndpoint_TCP> sCreateConnected( + ip_addr iRemoteHost, ip_port iRemotePort); + static ZRef<ZNetEndpoint_TCP> sCreateConnectedEndpoint( ip_addr iRemoteHost, ip_port iRemotePort); }; Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.cpp 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.cpp 2008-10-28 02:37:07 UTC (rev 167) @@ -20,41 +20,17 @@ #include "zoolib/ZNet_Internet_Socket.h" -// ================================================================================================= #if ZCONFIG_API_Enabled(Net_Internet_Socket) #include "zoolib/ZMemory.h" -#include "zoolib/ZTime.h" -#include <unistd.h> - -#ifndef errno -# include <errno.h> -#endif - -#include <signal.h> - -#include <stdio.h> -#include <fcntl.h> +#include <errno.h> #include <arpa/inet.h> - -// See comment in Solaris' /usr/include/sys/ioctl.h -#if __sun__ -# define BSD_COMP -#endif -#include <sys/ioctl.h> - -#include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> +#include <netinet/tcp.h> +#include <sys/socket.h> -// AG 2005-01-04. It looks like poll.h is not always present on MacOS X. -// We don't use poll on MacOS, so we can just skip the include for now. -#ifndef __APPLE__ -# define POLL_NO_WARN // Switch off Apple warning re poll(). -# include <poll.h> -#endif - using std::string; // ================================================================================================= @@ -112,210 +88,8 @@ #pragma mark - #pragma mark * Helper functions -// On MacOS X (and FreeBSD) and Linux a send or receive on a socket where the other end -// has closed can cause delivery of a sigpipe. These helper functions, and the conditional -// code in the ZNetEndpoint_TCP_Socket constructor, work around that issue. - -#ifdef __APPLE__ -// For MacOS X we set an option on the socket to indicate that sigpipe should not -// be delivered when the far end closes on us. That option was not defined in headers -// prior to 10.2, so we define it ourselves if necessary. - -#ifndef SO_NOSIGPIPE -# define SO_NOSIGPIPE 0x1022 -#endif - -#ifndef TCP_NODELAY -# include <netinet/tcp.h> -#endif - -static void sSetSocketOptions(int iSocket) - { - // Set the socket to be non blocking - ::fcntl(iSocket, F_SETFL, ::fcntl(iSocket, F_GETFL,0) | O_NONBLOCK); - - // Enable keep alive - int keepAliveFlag = 1; - ::setsockopt(iSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&keepAliveFlag, sizeof(keepAliveFlag)); - - // Disable sigpipe when writing/reading a far-closed socket. - int noSigPipeFlag = 1; - ::setsockopt(iSocket, SOL_SOCKET, SO_NOSIGPIPE, (char*)&noSigPipeFlag, sizeof(noSigPipeFlag)); - - // There's no simple way to flush a socket under MacOS X. We could hold on to the last byte - // written, then set NODELAY, write the byte, and clear NODELAY. I don't want to munge - // this code to do that right now. So for the moment on MacOS X we simply set NODELAY and - // expect higher level code to do buffering if it doesn't want to flood the connection with - // lots of small packets. This is a reasonable expectation because it's what has to be done - // anyway under Linux to prevent Nagle algorithm from kicking in. - int noDelayFlag = 1; - ::setsockopt(iSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&noDelayFlag, sizeof(noDelayFlag)); - } - -static int sSend(int iSocket, const char* iSource, size_t iCount) - { return ::send(iSocket, iSource, iCount, 0); } - -static int sReceive(int iSocket, char* iDest, size_t iCount) - { return ::recv(iSocket, iDest, iCount, 0); } - -static bool sWaitReadable(int iSocket, int iMilliseconds) - { - fd_set readSet, exceptSet; - FD_ZERO(&readSet); - FD_ZERO(&exceptSet); - FD_SET(iSocket, &readSet); - FD_SET(iSocket, &exceptSet); - - struct timeval timeOut; - timeOut.tv_sec = iMilliseconds / 1000; - timeOut.tv_usec = (iMilliseconds % 1000) * 1000; - return 0 < ::select(iSocket + 1, &readSet, nil, &exceptSet, &timeOut); - } - -static void sWaitWriteable(int iSocket) - { - fd_set writeSet; - FD_ZERO(&writeSet); - FD_SET(iSocket, &writeSet); - - struct timeval timeOut; - timeOut.tv_sec = 1; - timeOut.tv_usec = 0; - - ::select(iSocket + 1, nil, &writeSet, nil, &timeOut); - } - -#elif defined(linux) || defined(__sun__) - -// RedHat Linux 6.1 adds the sigpipe on closed behavior to recv and send, and also adds -// a new flag that can be passed to supress that behavior. Older kernels return EINVAL -// if they don't recognize the flag, and thus don't have the behavior. So we use a static -// bool to remember if MSG_NOSIGNAL is available in the kernel. - -static void sSetSocketOptions(int iSocket) - { - // Set the socket to be non blocking - ::fcntl(iSocket, F_SETFL, ::fcntl(iSocket, F_GETFL,0) | O_NONBLOCK); - - // Enable keep alive - int keepAliveFlag = 1; - ::setsockopt(iSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&keepAliveFlag, sizeof(keepAliveFlag)); - } - -#ifndef MSG_NOSIGNAL -# define MSG_NOSIGNAL 0x2000 -#endif - -static bool sCanUse_MSG_NOSIGNAL = false; -static bool sChecked_MSG_NOSIGNAL = false; - -static int sSend(int iSocket, const char* iSource, size_t iCount) - { - if (sCanUse_MSG_NOSIGNAL) - { - return ::send(iSocket, iSource, iCount, MSG_NOSIGNAL); - } - else - { - if (sChecked_MSG_NOSIGNAL) - { - return ::send(iSocket, iSource, iCount, 0); - } - else - { - int result = ::send(iSocket, iSource, iCount, MSG_NOSIGNAL); - if (result >= 0) - { - sCanUse_MSG_NOSIGNAL = true; - sChecked_MSG_NOSIGNAL = true; - } - else - { - if (errno == EINVAL) - { - sChecked_MSG_NOSIGNAL = true; - return ::send(iSocket, iSource, iCount, 0); - } - } - return result; - } - } - } - -static int sReceive(int iSocket, char* iDest, size_t iCount) - { - if (sCanUse_MSG_NOSIGNAL) - { - return ::recv(iSocket, iDest, iCount, MSG_NOSIGNAL); - } - else - { - if (sChecked_MSG_NOSIGNAL) - { - return ::recv(iSocket, iDest, iCount, 0); - } - else - { - int result = ::recv(iSocket, iDest, iCount, MSG_NOSIGNAL); - - if (result >= 0) - { - sCanUse_MSG_NOSIGNAL = true; - sChecked_MSG_NOSIGNAL = true; - } - else - { - if (errno == EINVAL) - { - sChecked_MSG_NOSIGNAL = true; - return ::recv(iSocket, iDest, iCount, 0); - } - } - return result; - } - } - } - -static bool sWaitReadable(int iSocket, int iMilliseconds) - { - pollfd thePollFD; - thePollFD.fd = iSocket; - thePollFD.events = POLLIN | POLLPRI; - thePollFD.revents = 0; - return 0 < ::poll(&thePollFD, 1, iMilliseconds); - } - -static void sWaitWriteable(int iSocket) - { - pollfd thePollFD; - thePollFD.fd = iSocket; - thePollFD.events = POLLOUT; - ::poll(&thePollFD, 1, 1000); - } - -#endif - // ================================================================================================= #pragma mark - -#pragma mark * ZNet_Internet_Socket - -ZNet::Error ZNet_Internet_Socket::sTranslateError(int iNativeError) - { - ZNet::Error theError = ZNet::errorGeneric; - switch (iNativeError) - { - case EADDRINUSE: theError = ZNet::errorLocalPortInUse; break; - case EINVAL: theError = ZNet::errorBadState; break; - case EBADF: theError = ZNet::errorBadState; break; - case ECONNREFUSED: theError = ZNet::errorCouldntConnect; break; - case 0: theError = ZNet::errorNone; break; - default: break; - } - return theError; - } - -// ================================================================================================= -#pragma mark - #pragma mark * ZNetNameLookup_Internet_Socket ZNetNameLookup_Internet_Socket::ZNetNameLookup_Internet_Socket( @@ -423,16 +197,6 @@ #pragma mark - #pragma mark * ZNetListener_TCP_Socket -static bool sFastCancellationEnabled; - -ZNetListener_TCP_Socket::ZNetListener_TCP_Socket( - int iFD, size_t iListenQueueSize, bool iKnowWhatImDoing) - { - ZAssert(iKnowWhatImDoing); - fSocketFD = iFD; - this->pInitRemainder(iListenQueueSize); - } - ZRef<ZNetListener_TCP_Socket> ZNetListener_TCP_Socket::sCreateWithFD(int iFD, size_t iListenQueueSize) { try @@ -444,204 +208,143 @@ return ZRef<ZNetListener_TCP_Socket>(); } -ZNetListener_TCP_Socket::ZNetListener_TCP_Socket(ip_port iLocalPort, size_t iListenQueueSize) +static int sEnsureInet(int iSocketFD) { - this->pInit(INADDR_ANY, iLocalPort, iListenQueueSize); - } - -ZNetListener_TCP_Socket::ZNetListener_TCP_Socket( - ip_addr iLocalAddress, ip_port iLocalPort, size_t iListenQueueSize) - { - this->pInit(iLocalAddress, iLocalPort, iListenQueueSize); - } - -ZNetListener_TCP_Socket::~ZNetListener_TCP_Socket() - { - ::close(fSocketFD); - } - -ZRef<ZNetEndpoint> ZNetListener_TCP_Socket::Listen() - { - fMutexNR.Acquire(); - while (fThreadID_Listening) - fCondition.Wait(fMutexNR); - fThreadID_Listening = ZThread::sCurrentID(); - - int sleepTime; - if (sFastCancellationEnabled) - sleepTime = 10000; - else - sleepTime = 1000; - - fMutexNR.Release(); - - sWaitReadable(fSocketFD, sleepTime); - - sockaddr_in remoteSockAddr; - ZBlockSet(&remoteSockAddr, sizeof(remoteSockAddr), 0); - socklen_t addrSize = sizeof(remoteSockAddr); - int result = ::accept(fSocketFD, (sockaddr*)&remoteSockAddr, &addrSize); - - fMutexNR.Acquire(); - - fThreadID_Listening = 0; - fCondition.Broadcast(); - fMutexNR.Release(); - - if (result > 0) + sockaddr_in localSockAddr; + socklen_t length = sizeof(localSockAddr); + if (::getsockname(iSocketFD, (sockaddr*)&localSockAddr, &length) >= 0) { - try - { - return new ZNetEndpoint_TCP_Socket(result); - } - catch (...) - {} + if (localSockAddr.sin_family == AF_INET) + return iSocketFD; } - - return ZRef<ZNetEndpoint>(); + throw std::runtime_error("ZNetListener_TCP_Socket, not an inet socket"); } -void ZNetListener_TCP_Socket::CancelListen() +ZNetListener_TCP_Socket::ZNetListener_TCP_Socket( + int iSocketFD, size_t iListenQueueSize, bool iKnowWhatImDoing) +: ZNetListener_Socket(sEnsureInet(iSocketFD), iListenQueueSize) { - fMutexNR.Acquire(); - - // It's not essential that we do anything here other than wait for a call to Listen - // to drop out. However, if sFastCancellationEnabled, then we issue a SIGALRM to - // the blocked thread, which will drop out of its call to poll or select with - // an inncoccuous EINTR. - - #if ZCONFIG(API_Thread, POSIX) - if (sFastCancellationEnabled && fThreadID_Listening) - { - ::pthread_kill(fThreadID_Listening, SIGALRM); - } - #endif - - while (fThreadID_Listening) - fCondition.Wait(fMutexNR); - - fMutexNR.Release(); + // We could ensure that iSocketFD + ZAssert(iKnowWhatImDoing); } -ip_port ZNetListener_TCP_Socket::GetPort() +static int sListen(ip_addr iLocalAddress, ip_port iLocalPort) { - sockaddr_in localSockAddr; - socklen_t length = sizeof(localSockAddr); - if (::getsockname(fSocketFD, (sockaddr*)&localSockAddr, &length) >= 0) - return ntohs(localSockAddr.sin_port); - return 0; - } - -void ZNetListener_TCP_Socket::pInit( - ip_addr iLocalAddress, ip_port iLocalPort, size_t iListenQueueSize) - { - fSocketFD = ::socket(PF_INET, SOCK_STREAM, 0); - if (fSocketFD < 0) + int theSocketFD = ::socket(PF_INET, SOCK_STREAM, 0); + if (theSocketFD < 0) { int err = errno; - throw ZNetEx(sTranslateError(err)); + throw ZNetEx(ZNet_Socket::sTranslateError(err)); } + // Enable SO_REUSEADDR, cause it's a real pain waiting for TIME_WAIT to expire + int reuseAddrFlag = 1; + ::setsockopt( + theSocketFD, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseAddrFlag, sizeof(reuseAddrFlag)); + sockaddr_in localSockAddr; ZBlockSet(&localSockAddr, sizeof(localSockAddr), 0); localSockAddr.sin_family = AF_INET; localSockAddr.sin_port = htons(iLocalPort); localSockAddr.sin_addr.s_addr = htonl(iLocalAddress); - // Enable SO_REUSEADDR, cause it's a real pain waiting for TIME_WAIT to expire - int reuseAddrFlag = 1; - ::setsockopt(fSocketFD, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseAddrFlag, sizeof(reuseAddrFlag)); - - if (::bind(fSocketFD, (sockaddr*)&localSockAddr, sizeof(localSockAddr)) < 0) + if (::bind(theSocketFD, (sockaddr*)&localSockAddr, sizeof(localSockAddr)) < 0) { int err = errno; - ::close(fSocketFD); - throw ZNetEx(sTranslateError(err)); + ::close(theSocketFD); + throw ZNetEx(ZNet_Socket::sTranslateError(err)); } - - this->pInitRemainder(iListenQueueSize); + return theSocketFD; } -void ZNetListener_TCP_Socket::pInitRemainder(size_t iListenQueueSize) - { - if (::listen(fSocketFD, iListenQueueSize) < 0) - { - int err = errno; - ::close(fSocketFD); - throw ZNetEx(sTranslateError(err)); - } - ::fcntl(fSocketFD, F_SETFL, ::fcntl(fSocketFD, F_GETFL,0) | O_NONBLOCK); +ZNetListener_TCP_Socket::ZNetListener_TCP_Socket(ip_port iLocalPort, size_t iListenQueueSize) +: ZNetListener_Socket(sListen(0, iLocalPort), iListenQueueSize) + {} - fThreadID_Listening = 0; - } +ZNetListener_TCP_Socket::ZNetListener_TCP_Socket( + ip_addr iLocalAddress, ip_port iLocalPort, size_t iListenQueueSize) +: ZNetListener_Socket(sListen(iLocalAddress, iLocalPort), iListenQueueSize) + {} -static void sDummyAction(int iSignal) +ZNetListener_TCP_Socket::~ZNetListener_TCP_Socket() {} -void ZNetListener_TCP_Socket::sEnableFastCancellation() +ip_port ZNetListener_TCP_Socket::GetPort() { - #if ZCONFIG(API_Thread, POSIX) - struct sigaction sigaction_new; - sigaction_new.sa_handler = sDummyAction; - sigaction_new.sa_flags = 0; - sigemptyset(&sigaction_new.sa_mask); - ::sigaction(SIGALRM, &sigaction_new, nil); - sFastCancellationEnabled = true; - #endif + sockaddr_in localSockAddr; + socklen_t length = sizeof(localSockAddr); + if (::getsockname(this->GetSocketFD(), (sockaddr*)&localSockAddr, &length) >= 0) + return ntohs(localSockAddr.sin_port); + return 0; } +ZRef<ZNetEndpoint> ZNetListener_TCP_Socket::Imp_MakeEndpoint(int iSocketFD) + { + return new ZNetEndpoint_TCP_Socket(iSocketFD); + } + // ================================================================================================= #pragma mark - #pragma mark * ZNetEndpoint_TCP_Socket -ZNetEndpoint_TCP_Socket::ZNetEndpoint_TCP_Socket(int iSocketFD) +static void sSetSocketOptions(int iSocketFD) { - fSocketFD = iSocketFD; - ZAssertStop(2, fSocketFD != -1); + // There's no simple way to flush a socket under MacOS X. We could hold on to the last byte + // written, then set NODELAY, write the byte, and clear NODELAY. I don't want to munge + // this code to do that right now. So for the moment on MacOS X we simply set NODELAY and + // expect higher level code to do buffering if it doesn't want to flood the connection with + // lots of small packets. This is a reasonable expectation because it's what has to be done + // anyway under Linux to prevent Nagle algorithm from kicking in. + int noDelayFlag = 1; + ::setsockopt(iSocketFD, IPPROTO_TCP, TCP_NODELAY, (char*)&noDelayFlag, sizeof(noDelayFlag)); + } - sSetSocketOptions(fSocketFD); +ZNetEndpoint_TCP_Socket::ZNetEndpoint_TCP_Socket(int iSocketFD) +: ZNetEndpoint_Socket(iSocketFD) + { + sSetSocketOptions(this->GetSocketFD()); } -ZNetEndpoint_TCP_Socket::ZNetEndpoint_TCP_Socket(ip_addr iRemoteHost, ip_port iRemotePort) +static int sConnect(ip_addr iRemoteHost, ip_port iRemotePort) { - fSocketFD = ::socket(PF_INET, SOCK_STREAM, 0); - if (fSocketFD < 0) - throw ZNetEx(sTranslateError(errno)); + int socketFD = ::socket(PF_INET, SOCK_STREAM, 0); + if (socketFD < 0) + throw ZNetEx(ZNet_Socket::sTranslateError(errno)); sockaddr_in remoteSockAddr; ZBlockSet(&remoteSockAddr, sizeof(remoteSockAddr), 0); remoteSockAddr.sin_family = AF_INET; remoteSockAddr.sin_port = htons(iRemotePort); remoteSockAddr.sin_addr.s_addr = htonl(iRemoteHost); - if (::connect(fSocketFD, (sockaddr*)&remoteSockAddr, sizeof(remoteSockAddr)) < 0) + if (::connect(socketFD, (sockaddr*)&remoteSockAddr, sizeof(remoteSockAddr)) < 0) { - ::close(fSocketFD); - throw ZNetEx(sTranslateError(errno)); + ::close(socketFD); + throw ZNetEx(ZNet_Socket::sTranslateError(errno)); } - - sSetSocketOptions(fSocketFD); + return socketFD; } -ZNetEndpoint_TCP_Socket::~ZNetEndpoint_TCP_Socket() +ZNetEndpoint_TCP_Socket::ZNetEndpoint_TCP_Socket(ip_addr iRemoteHost, ip_port iRemotePort) +: ZNetEndpoint_Socket(sConnect(iRemoteHost, iRemotePort)) { - ::close(fSocketFD); + sSetSocketOptions(this->GetSocketFD()); } -const ZStreamRCon& ZNetEndpoint_TCP_Socket::GetStreamRCon() - { return *this; } +ZNetEndpoint_TCP_Socket::~ZNetEndpoint_TCP_Socket() + {} -const ZStreamWCon& ZNetEndpoint_TCP_Socket::GetStreamWCon() - { return *this; } - ZRef<ZNetAddress> ZNetEndpoint_TCP_Socket::GetLocalAddress() { sockaddr_in localSockAddr; socklen_t length = sizeof(localSockAddr); - if (::getsockname(fSocketFD, (sockaddr*)&localSockAddr, &length) >= 0) + if (::getsockname(this->GetSocketFD(), (sockaddr*)&localSockAddr, &length) >= 0) { - return new ZNetAddress_Internet( - ntohl(localSockAddr.sin_addr.s_addr), ntohs(localSockAddr.sin_port)); + if (localSockAddr.sin_family == AF_INET) + { + return new ZNetAddress_Internet( + ntohl(localSockAddr.sin_addr.s_addr), ntohs(localSockAddr.sin_port)); + } } return ZRef<ZNetAddress>(); @@ -651,164 +354,18 @@ { sockaddr_in remoteSockAddr; socklen_t length = sizeof(remoteSockAddr); - if (::getpeername(fSocketFD, (sockaddr*)&remoteSockAddr, &length) >= 0) + if (::getpeername(this->GetSocketFD(), (sockaddr*)&remoteSockAddr, &length) >= 0) { - return new ZNetAddress_Internet( - ntohl(remoteSockAddr.sin_addr.s_addr), ntohs(remoteSockAddr.sin_port)); - } - - return ZRef<ZNetAddress>(); - } - -void ZNetEndpoint_TCP_Socket::Imp_Read(void* iDest, size_t iCount, size_t* oCountRead) - { - char* localDest = static_cast<char*>(iDest); - while (iCount) - { - int result = ::sReceive(fSocketFD, localDest, iCount); - - if (result < 0) + if (remoteSockAddr.sin_family == AF_INET) { - int err = errno; - if (err == EAGAIN) - { - sWaitReadable(fSocketFD, 1000); - } - else if (err != EINTR) - { - break; - } + return new ZNetAddress_Internet( + ntohl(remoteSockAddr.sin_addr.s_addr), ntohs(remoteSockAddr.sin_port)); } - else - { - if (result == 0) - { - // result is zero, indicating that the other end has sent FIN. - break; - } - else - { - localDest += result; - iCount -= result; - break; - } - } } - if (oCountRead) - *oCountRead = localDest - static_cast<char*>(iDest); - } -size_t ZNetEndpoint_TCP_Socket::Imp_CountReadable() - { - int localResult; - if (0 <= ::ioctl(fSocketFD, FIONREAD, &localResult)) - return localResult; - return 0; + return ZRef<ZNetAddress>(); } -void ZNetEndpoint_TCP_Socket::Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten) - { - const char* localSource = static_cast<const char*>(iSource); - while (iCount) - { - int result = ::sSend(fSocketFD, localSource, iCount); +// ================================================================================================= - if (result < 0) - { - int err = errno; - if (err == EAGAIN) - { - sWaitWriteable(fSocketFD); - } - else if (err != EINTR) - { - break; - } - } - else - { - if (result == 0) - { - // result is zero, indicating that the other end has closed its receive side. - break; - } - else - { - localSource += result; - iCount -= result; - } - } - } - if (oCountWritten) - *oCountWritten = localSource - static_cast<const char*>(iSource); - } - -bool ZNetEndpoint_TCP_Socket::Imp_WaitReadable(int iMilliseconds) - { - return sWaitReadable(fSocketFD, iMilliseconds); - } - -bool ZNetEndpoint_TCP_Socket::Imp_ReceiveDisconnect(int iMilliseconds) - { - ZTime endTime = ZTime::sSystem() + double(iMilliseconds) / 1000; - - bool gotIt = false; - for (;;) - { - int result = ::sReceive(fSocketFD, ZooLib::sGarbageBuffer, sizeof(ZooLib::sGarbageBuffer)); - if (result == 0) - { - // result is zero, indicating that the other end has sent FIN. - gotIt = true; - break; - } - else if (result < 0) - { - int err = errno; - if (err == EAGAIN) - { - if (iMilliseconds < 0) - { - sWaitReadable(fSocketFD, 1000); - } - else - { - ZTime now = ZTime::sSystem(); - if (endTime < now) - break; - sWaitReadable(fSocketFD, int(1000 * (endTime - now))); - } - } - else if (err != EINTR) - { - break; - } - } - } - return gotIt; - } - -void ZNetEndpoint_TCP_Socket::Imp_SendDisconnect() - { - ::shutdown(fSocketFD, SHUT_WR); - } - -void ZNetEndpoint_TCP_Socket::Imp_Abort() - { - // Cause a RST to be sent when we close(). See UNIX Network - // Programming, 2nd Ed, Stevens, page 423 - - struct linger theLinger; - theLinger.l_onoff = 1; - - // AG 2001-10-04. [Stevens] says that l_linger should be 0. The code previously set l_linger - // to be 1, I'm not sure if we found that to be correct in practice so I'm correcting it -- - // if we experience problems, let me know. - theLinger.l_linger = 0; - - ::setsockopt(fSocketFD, SOL_SOCKET, SO_LINGER, (char*)&theLinger, sizeof(theLinger)); - ::shutdown(fSocketFD, SHUT_RDWR); - } - #endif // ZCONFIG_API_Enabled(Net_Internet_Socket) -// ================================================================================================= Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.h 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Internet_Socket.h 2008-10-28 02:37:07 UTC (rev 167) @@ -24,37 +24,28 @@ #include "zoolib/ZCONFIG_API.h" #include "zoolib/ZCONFIG_SPI.h" +#include "zoolib/ZNet_Internet.h" +#include "zoolib/ZNet_Socket.h" + #ifndef ZCONFIG_API_Avail__Net_Internet_Socket -# define ZCONFIG_API_Avail__Net_Internet_Socket ZCONFIG_SPI_Enabled(POSIX) +# if ZCONFIG_API_Enabled(Net_Socket) +# define ZCONFIG_API_Avail__Net_Internet_Socket 1 +# endif #endif +#ifndef ZCONFIG_API_Avail__Net_Internet_Socket +# define ZCONFIG_API_Avail__Net_Internet_Socket 0 +#endif + #ifndef ZCONFIG_API_Desired__Net_Internet_Socket # define ZCONFIG_API_Desired__Net_Internet_Socket 1 #endif -#include "zoolib/ZNet_Internet.h" #if ZCONFIG_API_Enabled(Net_Internet_Socket) // ================================================================================================= - -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -// ================================================================================================= #pragma mark - -#pragma mark * ZNet_Internet_Socket - -class ZNet_Internet_Socket - { -public: - static ZNet::Error sTranslateError(int iNativeError); - }; - -// ================================================================================================= -#pragma mark - #pragma mark * ZNetNameLookup_Internet_Socket class ZNetNameLookup_Internet_Socket : public ZNetNameLookup @@ -84,33 +75,23 @@ #pragma mark - #pragma mark * ZNetListener_TCP_Socket -class ZNetListener_TCP_Socket : public ZNetListener_TCP, - private ZNet_Internet_Socket +class ZNetListener_TCP_Socket +: public ZNetListener_TCP, + public ZNetListener_Socket { ZNetListener_TCP_Socket(int iFD, size_t iListenQueueSize, bool iKnowWhatImDoing); public: static ZRef<ZNetListener_TCP_Socket> sCreateWithFD(int iFD, size_t iListenQueueSize); + ZNetListener_TCP_Socket(ip_port iLocalPort, size_t iListenQueueSize); ZNetListener_TCP_Socket(ip_addr iLocalAddress, ip_port iLocalPort, size_t iListenQueueSize); virtual ~ZNetListener_TCP_Socket(); -// From ZNetListener via ZNetListener_TCP - virtual ZRef<ZNetEndpoint> Listen(); - virtual void CancelListen(); - // From ZNetListener_TCP virtual ip_port GetPort(); - static void sEnableFastCancellation(); - -protected: - void pInit(ip_addr iLocalAddress, ip_port iLocalPort, size_t iListenQueueSize); - void pInitRemainder(size_t iListenQueueSize); - - ZMutexNR fMutexNR; - ZCondition fCondition; - int fSocketFD; - ZThread::ThreadID fThreadID_Listening; +// From ZNetListener_Socket + virtual ZRef<ZNetEndpoint> Imp_MakeEndpoint(int iSocketFD); }; // ================================================================================================= @@ -119,9 +100,7 @@ class ZNetEndpoint_TCP_Socket : public ZNetEndpoint_TCP, - private ZStreamRCon, - private ZStreamWCon, - private ZNet_Internet_Socket + public ZNetEndpoint_Socket { public: ZNetEndpoint_TCP_Socket(int iSocketFD); @@ -129,35 +108,9 @@ virtual ~ZNetEndpoint_TCP_Socket(); -// From ZStreamerRCon via ZNetEndpoint_TCP - virtual const ZStreamRCon& GetStreamRCon(); - -// From ZStreamerWCon via ZNetEndpoint_TCP - virtual const ZStreamWCon& GetStreamWCon(); - // From ZNetEndpoint via ZNetEndpoint_TCP virtual ZRef<ZNetAddress> GetLocalAddress(); virtual ZRef<ZNetAddress> GetRemoteAddress(); - -// From ZStreamR via ZStreamRCon - virtual void Imp_Read(void* iDest, size_t iCount, size_t* oCountRead); - virtual size_t Imp_CountReadable(); - -// From ZStreamW via ZStreamWCon - virtual void Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten); - -// From ZStreamRCon - virtual bool Imp_WaitReadable(int iMilliseconds); - virtual bool Imp_ReceiveDisconnect(int iMilliseconds); - -// From ZStreamWCon - virtual void Imp_SendDisconnect(); - -// From ZStreamRCon and ZStreamWCon - virtual void Imp_Abort(); - -private: - int fSocketFD; }; // ================================================================================================= Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Local.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Local.cpp 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Local.cpp 2008-10-28 02:37:07 UTC (rev 167) @@ -51,7 +51,7 @@ {} ZRef<ZNetEndpoint> ZNetAddress_Local::Connect() const - { return ZNetEndpoint_Local::sCreateConnectedEndpoint(fPath); } + { return ZNetEndpoint_Local::sCreateConnected(fPath); } const string& ZNetAddress_Local::GetPath() const { return fPath ;} @@ -90,7 +90,7 @@ #pragma mark - #pragma mark * ZNetListener_Local -ZRef<ZNetListener_Local> ZNetListener_Local::sCreateListener( +ZRef<ZNetListener_Local> ZNetListener_Local::sCreate( const string& iPath, size_t iListenQueueSize) { return ZFactoryChain_T<ZRef<ZNetListener_Local>, MakeParam_t> @@ -101,8 +101,7 @@ #pragma mark - #pragma mark * ZNetEndpoint_Local -ZRef<ZNetEndpoint_Local> ZNetEndpoint_Local::sCreateConnectedEndpoint( - const string& iPath) +ZRef<ZNetEndpoint_Local> ZNetEndpoint_Local::sCreateConnected(const string& iPath) { return ZFactoryChain_T<ZRef<ZNetEndpoint_Local>, MakeParam_t> ::sMake(MakeParam_t(iPath)); Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Local.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Local.h 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Local.h 2008-10-28 02:37:07 UTC (rev 167) @@ -83,7 +83,7 @@ public: typedef ZMulti_T2<std::string, size_t> MakeParam_t; - static ZRef<ZNetListener_Local> sCreateListener( + static ZRef<ZNetListener_Local> sCreate( const std::string& iPath, size_t iListenQueueSize); }; @@ -96,8 +96,7 @@ public: typedef std::string MakeParam_t; - static ZRef<ZNetEndpoint_Local> sCreateConnectedEndpoint( - const std::string& iPath); + static ZRef<ZNetEndpoint_Local> sCreateConnected(const std::string& iPath); }; #endif // __ZNet_Local__ Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Local_Socket.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Local_Socket.cpp 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Local_Socket.cpp 2008-10-28 02:37:07 UTC (rev 167) @@ -20,20 +20,11 @@ #include "zoolib/ZNet_Local_Socket.h" -// ================================================================================================= #if ZCONFIG_API_Enabled(Net_Local_Socket) #include "zoolib/ZMemory.h" -#include "zoolib/ZTime.h" -#include <unistd.h> - -#ifndef errno -# include <errno.h> -#endif - -#include <fcntl.h> - +#include <errno.h> #include <sys/socket.h> #include <sys/un.h> @@ -177,6 +168,8 @@ localSockAddr.sun_family = AF_LOCAL; strcpy(localSockAddr.sun_path, iPath.c_str()); + ::unlink(localSockAddr.sun_path); + if (::bind(theSocketFD, (sockaddr*)&localSockAddr, sizeof(localSockAddr)) < 0) { int err = errno; @@ -252,5 +245,6 @@ return ZRef<ZNetAddress>(); } -#endif // ZCONFIG_API_Enabled(Net_Local_Socket) // ================================================================================================= + +#endif // ZCONFIG_API_Enabled(Net_Local_Socket) Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Socket.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Socket.cpp 2008-10-28 01:42:20 UTC (rev 166) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Socket.cpp 2008-10-28 02:37:07 UTC (rev 167) @@ -20,33 +20,21 @@ #include "zoolib/ZNet_Socket.h" -// ================================================================================================= #if ZCONFIG_API_Enabled(Net_Socket) #include "zoolib/ZMemory.h" #include "zoolib/ZTime.h" -#include <unistd.h> - -#ifndef errno -# include <errno.h> -#endif - +#include <errno.h> +#include <fcntl.h> #include <signal.h> -#include <stdio.h> -#include <fcntl.h> -//#include <arpa/inet.h> - // See comment in Solaris' /usr/include/sys/ioctl.h #if __sun__ # define BSD_COMP #endif #include <sys/ioctl.h> - #include <sys/socket.h> -//#include <netdb.h> -//#include <netinet/in.h> // AG 2005-01-04. It looks like poll.h is not always present on MacOS X. // We don't use poll on MacOS, so we can just skip the include for now. @@ -297,7 +285,7 @@ sWaitReadable(fSocketFD, sleepTime); - char remoteSockAddr[128]; + char remoteSockAddr[1024]; ZBlockSet(&remoteSockAddr, sizeof(remoteSockAddr), 0); socklen_t addrSize = sizeof(remoteSockAddr); int result = ::accept(fSocketFD, (sockaddr*)&remoteSockAddr, &addrSize); @@ -539,4 +527,5 @@ } // ================================================================================================= + #endif // ZCONFIG_API_Enabled(Net_Socket) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |