XPCSocket::XPCSocket(const char *_sProtocol, int _iPort) { iPort = _iPort; iBlocking = 0; try { // Retrieve the socket protocol XPCGetProtocol socketProtocol(_sProtocol); // If the protocol is UDP a UDP socket is created if (strcmp(socketProtocol.sGetProtocolName(), "udp") == 0) { if ((iSocket = socket(AF_INET, SOCK_DGRAM, socketProtocol.iGetProtocolNumber())) == -1) { char sMsg[512]; sprintf(sMsg, "Error opening socket: %s", sGetError()); XPCException socketExcept(sMsg); throw socketExcept; return; } } // If the protocol is TCP a TCP socket is created else if (strcmp(socketProtocol.sGetProtocolName(), "tcp") == 0) { if ((iSocket = socket(AF_INET, SOCK_STREAM, socketProtocol.iGetProtocolNumber())) == -1) { char sMsg[512]; sprintf(sMsg, "Error opening socket: %s", sGetError()); XPCException socketExcept(sMsg); throw socketExcept; return; } } } catch(XPCException &exceptObject) { char sMsg[512]; sprintf(sMsg, "Protocol Error Definition: %s", exceptObject.sGetException()); XPCException socketExcept(sMsg); throw socketExcept; return; } // The client address is initialized to all addresses at the specified port clientAddress.sin_family = AF_INET; clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); clientAddress.sin_port = htons(iPort); }
void XPCSocket::vSetSocketBlocking(int _iToggle) { char sMsg[512]; if (_iToggle) { if (iGetSocketBlocking()) return; else { iBlocking = 1; // Socket blocking is turned ON #ifdef WINDOWS_NT if (ioctlsocket(iSocket, FIONBIO, (unsigned long *)&iBlocking) == -1) #else if (ioctl(iSocket, FIONBIO, (char *)&iBlocking) == -1) #endif { sprintf(sMsg, "Error Turning ON Socket Blocking Status: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } } } else { if (!iGetSocketBlocking()) return; else { iBlocking = 0; // Socket blocking is turned off #ifdef WINDOWS_NT if (ioctlsocket(iSocket, FIONBIO, (unsigned long *)&iBlocking) == -1) #else if (ioctl(iSocket, FIONBIO, (char *)&iBlocking) == -1) #endif { sprintf(sMsg, "Error Turning OFF Socket Blocking Status: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } } } }
int XPCTcpSocket::iRecieveMessage(void *_vMessage, int _iMessageSize, int _iOption) { int iNumBytes; // The number of bytes recieved #ifdef WINDOWS_NT if (_iOption == MSG_WAITALL) // If the option is MSG_WAITALL and this is a WINDOW_NT machinecall iReceiveMessageAll // to process it return iRecieveMessageAll(_vMessage, _iMessageSize); #endif // Recieves a TCP socket message. The number of bytes received isreturned iNumBytes = recv(iSocket, (char *)_vMessage, _iMessageSize, _iOption); if (iNumBytes == -1) { // If the reason for failure is a client disconnect, anexception is not thrown. // The number of bytes returned is 0 #ifdef UNIX if (errno == ECONNRESET) return 0; #else if (WSAGetLastError() == WSAECONNRESET) return 0; #endif char sMsg[512]; sprintf(sMsg, "Error receiving on socket: %s", sGetError()); printf("%s\n",sMsg); throw XPCException(sMsg); } return iNumBytes; }
void XPCTcpSocket::vListen(int _iNumPorts) { // Incoming connections are listened for if (listen(iSocket, _iNumPorts) == -1) { char sMsg[512]; sprintf(sMsg, "Error Listening To Socket. %s", sGetError()); throw XPCException(sMsg);; return; } }
void XPCTcpSocket::vBindSocket() { // Bind the socket to the given address and port number if (bind(iSocket, (struct sockaddr *)&clientAddress,sizeof(clientAddress)) == -1) { char sMsg[512]; sprintf(sMsg, "Error binding to socket: %s", sGetError()); XPCException socketExcept(sMsg); throw socketExcept; return; } }
void XPCSocket::vSetDebug(int _iToggle) { if (setsockopt(iSocket, SOL_SOCKET, SO_DEBUG, (char *)&_iToggle, sizeof(_iToggle)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting Debug Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vSetRecieveTimeOut(int nTimeOut) { if (setsockopt(iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&nTimeOut, sizeof(nTimeOut)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting ReciveTimeOut Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vSetRecieveBuf(int _iRecieveBufSize) { if (setsockopt(iSocket, SOL_SOCKET, SO_SNDBUF, (char *)&_iRecieveBufSize, sizeof(_iRecieveBufSize)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting RecieveBufSize Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vSetKeepAlive(int _iToggle) { if (setsockopt(iSocket, SOL_SOCKET, SO_KEEPALIVE, (char *)&_iToggle, sizeof(_iToggle)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting Keepalive Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vSetReuseAddr(int _iToggle) { if (setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&_iToggle, sizeof(_iToggle)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting Reuseaddr Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vSetBroadcast(int _iToggle) { if (setsockopt(iSocket, SOL_SOCKET, SO_BROADCAST, (char *)&_iToggle, sizeof(_iToggle)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting Broadcast Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vSetLinger(struct linger _lingerOption) { if (setsockopt(iSocket, SOL_SOCKET, SO_LINGER, (char *)&_lingerOption, sizeof(struct linger)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Setting Linger Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } }
void XPCSocket::vGetLinger(struct linger &_lingerOption) { int iOptionLen = sizeof(struct linger); if (getsockopt(iSocket, SOL_SOCKET, SO_LINGER, (char *)&_lingerOption,(socklen_t*) &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Extracting Linger Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return; } return; }
int XPCSocket::iGetReuseAddr() { int iGetOption; int iOptionLen = sizeof(iGetOption); if (getsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&iGetOption,(socklen_t*) &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Extracting Resuseaddr Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return -1; } return iGetOption; }
int XPCSocket::iGetBroadcast() { int iGetOption; int iOptionLen = sizeof(iGetOption); if (getsockopt(iSocket, SOL_SOCKET, SO_BROADCAST, (char *)&iGetOption,(socklen_t*) &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Extracting Broadcast Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return -1; } return iGetOption; }
int XPCSocket::iGetSendBuf() { int iSendBuf; int iOptionLen = sizeof(iSendBuf); if (getsockopt(iSocket, SOL_SOCKET, SO_SNDBUF, (char *)&iSendBuf, &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Extracting SendBuf Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return -1; } return iSendBuf; }
int XPCSocket::iGetKeepAlive() { int iGetOption; int iOptionLen = sizeof(iGetOption); if (getsockopt(iSocket, SOL_SOCKET, SO_KEEPALIVE, (char *)&iGetOption,(socklen_t*) &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Extracting Keepalive Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return -1; } return iGetOption; }
int XPCSocket::iGetDebug() { int iGetOption; int iOptionLen = sizeof(iGetOption); if (getsockopt(iSocket, SOL_SOCKET, SO_DEBUG, (char *)&iGetOption,(socklen_t*) &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Recieving Debug Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return -1; } return iGetOption; }
XPCTcpSocket *XPCTcpSocket::Accept(char *_sHost) { short int iNewSocket; // Stores the new socket file descriptor struct sockaddr_in clientAddress; // Stores the connected clients info // Gets the length of the client's address int iClientAddressLen = sizeof(clientAddress); // Accepts a new client connection and stores its socket file descriptor if ((iNewSocket = accept(iSocket, (struct sockaddr *)&clientAddress,(socklen_t*)&iClientAddressLen)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Accepting Socket. %s", sGetError()); XPCException socketExcept(sMsg); throw socketExcept; return NULL; } // If the host name is requested if (_sHost != NULL) { // Get the ascii representation of the address char *sAddress = inet_ntoa((struct in_addr)clientAddress.sin_addr); // Get the host name given the address try { XPCGetHostInfo getHostInfo(sAddress, ADDRESS); // Store the host name strcpy(_sHost, getHostInfo.sGetHostName()); } catch(XPCException e) { strcpy(_sHost, sAddress); printf("INFO: %s using numeric address %s\n",e.sGetException(),_sHost); } } // Create and return the new XPCTcpSocket object XPCTcpSocket *newSocket = new XPCTcpSocket(iNewSocket); return newSocket; }
int XPCSocket::iGetRecieveBuf() { int iRcvBuf; int iOptionLen = sizeof(iRcvBuf); if (getsockopt(iSocket, SOL_SOCKET, SO_RCVBUF, (char *)&iRcvBuf,(socklen_t*) &iOptionLen) == -1) { char sMsg[512]; sprintf(sMsg, "Error Extracting RcvBuf Option: %s", sGetError()); XPCException sockOptExcept(sMsg); throw sockOptExcept; return -1; } return iRcvBuf; }
int XPCTcpSocket::iRecieveMessageAll(void *_vMessage, int _iMessageSize) { int iNumBytes = 0; // The number of bytes received int iCurrentSize = _iMessageSize; // The number of bytes wanted toreceive int iOffsetSize = 0; // The number of bytes currentlyrecieved // While the number of bytes received is less than the number requestedcontinue to // retrieve more data while (iNumBytes < iCurrentSize) { // The socket message is recieved and stored within the mesageoffset by the // offset number of bytes iNumBytes = recv(iSocket, (char *)_vMessage + iOffsetSize,iCurrentSize, 0); if (iNumBytes == -1) { // If the reason for failure is a client disconnect, an exception isnot thrown. // The number of bytes returned is 0 if (WSAGetLastError() == WSAECONNRESET) return 0; char sMsg[512]; sprintf(sMsg, "Error receiving on socket: %s", sGetError()); XPCException socketExcept(sMsg); throw socketExcept; return iNumBytes; } else if (iNumBytes == 0) return iNumBytes; // If the total number of bytes requested are not returned, theoffset is adjusted // and the number of bytes left to receive is also adjusted else if (iNumBytes < iCurrentSize) { iOffsetSize += iNumBytes; iCurrentSize = iCurrentSize - iNumBytes; iNumBytes = 0; } } return _iMessageSize; }
int XPCTcpSocket::iSendMessage(void *_vMessage, int _iMessageSize) { int iNumBytes; // Stores the number of bytes sent // Sends the message to the connected host #ifdef _WIN32 if ((iNumBytes = send(iSocket, (char *)_vMessage, _iMessageSize, 0)) == -1) #else if ((iNumBytes = send(iSocket, _vMessage, _iMessageSize, 0)) == -1) #endif { char sMsg[512]; sprintf(sMsg, "Error sending socket message: %s", sGetError()); throw XPCException(sMsg); return 0; } return iNumBytes; }
void XPCTcpSocket::vConnect(const char *_sHost) { struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(iPort); // Resolve the IP address of the given host name std::string sHost(_sHost); hostType HostType; if(sHost.find_first_not_of("0123456789. ")!=std::string::npos) { HostType = NAME; XPCGetHostInfo getHostInfo(_sHost, HostType); // Store the IP address and socket port number serverAddress.sin_addr.s_addr =inet_addr(getHostInfo.sGetHostAddress()); } else { HostType = ADDRESS; // Store the IP address and socket port number serverAddress.sin_addr.s_addr =inet_addr(_sHost); } // Connect to the given address if (connect(iSocket, (struct sockaddr *)&serverAddress,sizeof(serverAddress)) == -1) { char sMsg[512]; sprintf(sMsg, "Error Connecting To Socket. %s", sGetError()); XPCException socketExcept(sMsg); throw socketExcept; return; } }