Initial
This commit is contained in:
424
socket/Socket.cpp
Normal file
424
socket/Socket.cpp
Normal 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)));
|
||||
}
|
||||
Reference in New Issue
Block a user