This commit is contained in:
2024-08-07 09:16:27 -04:00
parent fdfadd5c7e
commit 5f971cf684
5200 changed files with 731717 additions and 0 deletions

424
socket/Socket.cpp Normal file
View File

@@ -0,0 +1,424 @@
#include <socket/socket.hpp>
#include <common/diskinfo.hpp>
#include <common/openfile.hpp>
#include <common/filemap.hpp>
#include <common/pview.hpp>
#include <common/profile.hpp>
#include <common/block.hpp>
bool Socket::create(Domain domain,Type type,Protocol protocol)
{
destroy();
if(!isInitialized())return isOkay();
mSocket=::socket((int)domain,(int)type,(int)protocol);
mReceiveCache.socket(mSocket);
mDisposition=CloseSocket;
return isOkay();
}
void Socket::destroy(void)
{
if(!isOkay()||!isInitialized())return;
if(CloseSocket==mDisposition)::closesocket(mSocket);
mSocket=INVALID_SOCKET;
isConnected(FALSE);
isBound(FALSE);
isListening(FALSE);
}
Socket &Socket::operator=(const Socket &someSocket)
{
destroy();
mSocket=someSocket.mSocket;
mReceiveCache.socket(mSocket);
mDisposition=AssumedSocket;
isConnected(someSocket.isConnected());
isBound(someSocket.isBound());
isListening(someSocket.isListening());
return *this;
}
Socket &Socket::operator=(SOCKET someSOCKET)
{
destroy();
mSocket=someSOCKET;
mReceiveCache.socket(mSocket);
mDisposition=CloseSocket;
isConnected(FALSE);
isBound(FALSE);
isListening(FALSE);
return *this;
}
DWORD Socket::receive(char *buffer,DWORD count,bool waitForData)
{
DWORD cbytes(0);
for(;cbytes<count;cbytes++)
{
if(!mReceiveCache.receive(*buffer,waitForData))break;
buffer++;
}
return cbytes;
}
bool Socket::receive(char &charData,bool waitForData)
{
if(!isConnected())return false;
if(!mReceiveCache.receive(charData,waitForData))return false;
return true;
}
bool Socket::receive(String &receiveString,bool waitForData)
{
char rcvChar;
receiveString.reserve(MaxLength);
while(TRUE)
{
if(!isConnected())return false;
if(!mReceiveCache.receive(rcvChar,waitForData))
{
if(receiveString.isNull())return false;
break;
}
if(rcvChar==0x0D)continue;
else if(rcvChar==0x0A)break;
else receiveString+=rcvChar;
}
return true;
}
bool Socket::receive(Block<String> &receiveStrings)
{
String stringData;
String seriesItem;
receiveStrings.remove();
while(TRUE)
{
if(!receive(stringData))break;
if(!receiveStrings.size())seriesItem=stringData.substr(0,2);
receiveStrings.insert(&stringData);
if(!(stringData.operator[](3)=='-'&&stringData.substr(0,2)==seriesItem))break;
if(!isConnected())break;
}
return true;
}
bool Socket::receiveFrom(void *pBuffer,int buflen,DWORD msgType,INETSocketAddress &from)
{
int fromLength(sizeof(sockaddr_in));
if(!isOkay()||!pBuffer||buflen<=0)return false;
return !(-1==::recvfrom(mSocket,(char*)pBuffer,buflen,msgType,(sockaddr*)&(from.getsockaddr()),&fromLength));
}
bool Socket::receivePage(Block<String> &receiveStrings)
{
String stringData;
receiveStrings.remove();
while(TRUE)
{
if(!receive(stringData))break;
receiveStrings.insert(&stringData);
if(stringData.substr(0,6)==String("</html>")||stringData.substr(0,6)==String("</HTML>"))break;
else if(stringData.substr(0,13)==String("</body></html>")||stringData.substr(0,13)==String("</BODY></HTML>"))break;
}
return true;
}
bool Socket::receiveHeader(Block<String> &headerLines)
{
String stringData;
headerLines.remove();
while(true)
{
if(!receive(stringData))break;
if(stringData.isNull())break;
stringData.lower();
headerLines.insert(&stringData);
}
return true;
}
bool Socket::receiveImage(String pathFileName,TimeInfo &someTimeInfo)
{
String strDirectory(pathFileName);
DiskInfo diskInfo;
Profile iniProfile;
char rcvChar[BlockLength];
DWORD bufferLength;
DWORD receiveCount(0);
Block<String> headerLines;
DWORD sizeData(0);
if(!isConnected())return false;
if(diskInfo.getDiskFreeSpace()<sizeData)return false;
if(pathFileName.isNull())return false;
if(iniProfile.makeDirectoryName(strDirectory))diskInfo.createDirectory(strDirectory);
receiveHeader(headerLines);
for(int lineIndex=0;lineIndex<headerLines.size();lineIndex++)
{
String &headerLine=headerLines[lineIndex];
if(headerLine.betweenString(0,':')==String("content-length"))sizeData=::atoi(headerLine.betweenString(':',0));
}
if(!sizeData)return receiveBinary(pathFileName,250000,someTimeInfo);
FileHandle writeFile(pathFileName,FileHandle::Write,FileHandle::ShareRead,FileHandle::Overwrite);
if(!writeFile.isOkay())return false;
someTimeInfo.startTime();
while(receiveCount<sizeData)
{
if(receiveCount+sizeof(rcvChar)>sizeData)bufferLength=sizeData-receiveCount;
else bufferLength=sizeof(rcvChar);
while(!mReceiveCache.isReady(FALSE));
mReceiveCache.receive(rcvChar,bufferLength,bufferLength);
if(!bufferLength)continue;
writeFile.write((unsigned char*)rcvChar,bufferLength);
receiveCount+=bufferLength;
if(!isConnected())break;
}
someTimeInfo.endTime(sizeData);
writeFile.close();
return true;
}
bool Socket::receiveBinary(String pathFileName,DWORD sizeData,TimeInfo &someTimeInfo)
{
String strDirectory(pathFileName);
DiskInfo diskInfo;
Profile iniProfile;
char rcvChar[BlockLength];
DWORD bufferLength;
DWORD receiveCount(0);
if(!isConnected())return false;
if(diskInfo.getDiskFreeSpace()<sizeData)return false;
if(pathFileName.isNull())return false;
if(iniProfile.makeDirectoryName(strDirectory))diskInfo.createDirectory(strDirectory);
FileHandle writeFile(pathFileName,FileHandle::Write,FileHandle::ShareRead,FileHandle::Overwrite);
if(!writeFile.isOkay())return false;
someTimeInfo.startTime();
while(receiveCount<sizeData)
{
if(receiveCount+sizeof(rcvChar)>sizeData)bufferLength=sizeData-receiveCount;
else bufferLength=sizeof(rcvChar);
while(!mReceiveCache.isReady(FALSE));
if(!mReceiveCache.receive(rcvChar,sizeof(rcvChar),bufferLength))break;
writeFile.write((unsigned char*)rcvChar,bufferLength);
receiveCount+=bufferLength;
if(!isConnected())break;
}
someTimeInfo.endTime(sizeData);
return false;
}
bool Socket::receiveBinary(String pathFileName,TimeInfo &someTimeInfo)
{
Profile iniProfile;
char rcvChar[BlockLength];
DWORD bufferLength(sizeof(rcvChar));
DWORD receiveCount(0);
if(!isConnected())return false;
iniProfile.makeFileName(pathFileName);
if(pathFileName.isNull())return false;
FileHandle writeFile(pathFileName,FileHandle::Write,FileHandle::ShareRead,FileHandle::Overwrite);
someTimeInfo.startTime();
while(true)
{
while(!mReceiveCache.isReady(false));
if(!mReceiveCache.receive(rcvChar,sizeof(rcvChar),bufferLength))break;
writeFile.write((unsigned char*)rcvChar,bufferLength);
receiveCount+=bufferLength;
if(!isConnected())break;
}
someTimeInfo.endTime(receiveCount);
return true;
}
bool Socket::send(const char *buffer,DWORD count)
{
if(!isConnected())return false;
if(!count)return false;
canWrite();
if(SOCKET_ERROR==::send(mSocket,buffer,count,0))return false;
return true;
}
bool Socket::send(const char &charData)
{
if(!isConnected())return false;
canWrite();
if(SOCKET_ERROR==::send(mSocket,&((char&)charData),sizeof(charData),0))return false;
return true;
}
bool Socket::send(Block<String> &strings)
{
for(int index=0;index<strings.size();index++)
{
if(!send(strings[index]))return false;
}
return true;
}
bool Socket::send(const String &sendString)
{
String strLineString;
String crlf("\r\n");
int strLength;
// if(!isConnected()||sendString.isNull())return false;
if(!isConnected())return false;
strLineString=sendString+crlf;
strLength=strLineString.length();
canWrite();
if(::send(mSocket,(LPSTR)((String&)strLineString),strLength,0)<strLength)return false;
return true;
}
bool Socket::sendBinary(String pathFileName,TimeInfo &someTimeInfo)
{
FileHandle sendFile(pathFileName,FileHandle::Read,FileHandle::ShareRead);
FileMap sendMap(sendFile);
PureViewOfFile sendView(sendMap);
char sndChar[BlockLength];
DWORD sndLength;
if(!sendFile.isOkay())return false;
someTimeInfo.startTime();
while(true)
{
sndLength=sendView.read(sndChar,sizeof(sndChar));
if(!sndLength)break;
canWrite();
if(SOCKET_ERROR==::send(mSocket,sndChar,sndLength,0))break;
if(!isConnected())break;
}
someTimeInfo.endTime(sendFile.size());
return true;
}
bool Socket::sendTo(void *pBuffer,int buflen,INETSocketAddress &inetSocketAddress)
{
if(!isOkay()||!pBuffer||!buflen)return false;
return ::sendto(mSocket,(const char*)pBuffer,buflen,0,(sockaddr*)&((sockaddr_in&)inetSocketAddress),sizeof(sockaddr_in))?true:false;
}
bool Socket::bind(INETSocketAddress &internetSocketAddress)
{
int nameLength(sizeof(sockaddr_in));
if(isConnected()||isBound())return false;
if(!isOkay()&&!create())return false;
if(!::bind(mSocket,(sockaddr*)&((sockaddr_in&)internetSocketAddress),sizeof(sockaddr)))isBound(true);
if(isBound())::getsockname(mSocket,(sockaddr*)&((sockaddr_in&)internetSocketAddress),&nameLength);
return isBound();
}
bool Socket::bind(SocketAddress &socketAddress)
{
if(isConnected()||isBound())return false;
if(!isOkay()&&!create())return false;
if(!::bind(mSocket,(sockaddr*)&((sockaddr_in&)socketAddress),SocketAddress::length()))isBound(true);
return isBound();
}
bool Socket::connect(INETSocketAddress &internetSocketAddress)
{
if(isConnected())return false;
if(!isOkay()&&!create())return false;
if(!::connect(mSocket,(sockaddr*)&((sockaddr_in&)internetSocketAddress),sizeof(sockaddr_in)))isConnected(TRUE);
return isConnected();
}
bool Socket::getSocketName(INETSocketAddress &internetSocketAddress)
{
int length(sizeof(sockaddr_in));
if(!isOkay())return false;
if(SOCKET_ERROR==::getsockname(mSocket,(sockaddr*)&((sockaddr_in&)internetSocketAddress),&length))return false;
return true;
}
bool Socket::getPeerName(INETSocketAddress &internetSocketAddress)
{
int length(sizeof(sockaddr_in));
if(!isConnected())return false;
if(SOCKET_ERROR==::getpeername(mSocket,(sockaddr*)&((sockaddr_in&)internetSocketAddress),&length))return false;
return true;
}
bool Socket::listen(int maxPendingRequests)
{
if(!isOkay()||!isBound())return FALSE;
if(!::listen(mSocket,maxPendingRequests))isListening(TRUE);
return isListening();
}
bool Socket::accept(Socket &someSocket)
{
someSocket.destroy();
if(!isOkay()||!isListening())return FALSE;
someSocket=::accept(mSocket,0,0);
if(someSocket.isOkay())someSocket.isConnected(TRUE);
return someSocket.isOkay();
}
bool Socket::accept(Socket &someSocket,INETSocketAddress &internetSocketAddress)
{
int addressLength(sizeof(sockaddr_in));
someSocket.destroy();
if(!isOkay()||!isListening())return FALSE;
someSocket=::accept(mSocket,(sockaddr*)&internetSocketAddress,&addressLength);
if(someSocket.isOkay())someSocket.isConnected(TRUE);
return someSocket.isOkay();
}
bool Socket::reuseAddress(bool reuseAddress)
{
int reuse(reuseAddress);
if(!isOkay())return false;
return !(::setsockopt(mSocket,SOL_SOCKET,SO_REUSEADDR,(char*)&reuse,sizeof(int)));
}
bool Socket::setLinger(int seconds)
{
LINGER linger;
if(!isOkay())return false;
linger.l_onoff=1;
linger.l_linger=seconds;
return !(::setsockopt(mSocket,SOL_SOCKET,SO_DONTLINGER,(char*)&linger,sizeof(linger)));
}
bool Socket::setDontLinger(void)
{
LINGER linger;
if(!isOkay())return false;
linger.l_onoff=0;
linger.l_linger=0;
return !(::setsockopt(mSocket,SOL_SOCKET,SO_DONTLINGER,(char*)&linger,sizeof(linger)));
}
bool Socket::addMembership(IPMReq &ipMReq)
{
return !(::setsockopt(mSocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&((ip_mreq&)ipMReq),IPMReq::length()));
}
bool Socket::dropMembership(IPMReq &ipMReq)
{
return !(::setsockopt(mSocket,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char*)&((ip_mreq&)ipMReq),IPMReq::length()));
}
bool Socket::setMulticastTTL(int ttl)
{
return !(::setsockopt(mSocket,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&ttl,sizeof(ttl)));
}
bool Socket::setMulticastLoopback(bool loopback)
{
int loop(loopback);
return !(::setsockopt(mSocket,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)&loop,sizeof(loop)));
}