Files
CPP/sstp/clientsocketsender.cpp
2025-12-16 18:23:21 -05:00

150 lines
4.3 KiB
C++

#include <sstp/clientsocketsender.hpp>
#include <common/utility.hpp>
/// @brief This is to provide a definition for SmartPointer
ClientSocketSender::ClientSocketSender()
: mIPAddress(""), mPort(0)
{
}
/// @brief Establish a connection to the socket specified by ipAddress and port
/// @param ipAddress The ipAddress
/// @param port The port
ClientSocketSender::ClientSocketSender(String ipAddress, int port)
: mIPAddress(ipAddress), mPort(port)
{
mSocket = ::socket(AF_INET,SOCK_STREAM,0);
if(!isOkay())
{
std::cout << "Unable to initialize socket " << std::endl;
return;
}
mInternalSocketAddress.sin_family = AF_INET;
mInternalSocketAddress.sin_port= ::htons(mPort);
int result = ::inet_pton(AF_INET, ipAddress.str(), &mInternalSocketAddress.sin_addr);
if(result<0)
{
std::cout << "Unable to convert ipaddress to network address" << std::endl;
close();
return;
}
result = ::connect(mSocket, (struct sockaddr*)&mInternalSocketAddress, sizeof(mInternalSocketAddress));
if(result<0)
{
close();
std::cout << "Unable to connect to host " << mIPAddress << ":" << mPort << std::endl;
}
}
/// @brief Close the connection on destruction
ClientSocketSender::~ClientSocketSender()
{
std::cout << "~ClientSocketSender" << std::endl;
close();
}
/// @brief Closes the connection
/// @param
void ClientSocketSender::close(void)
{
if(-1==mSocket)return;
std::cout << "ClientSocketSender::close, closing socket" << std::endl;
::close(mSocket);
mSocket=-1;
}
/// @brief Send the specified file through the connection
/// @param pathFileName The file to send
/// @return Returns true if successful
bool ClientSocketSender::sendFile(String &pathFileName)
{
Profiler profiler;
FileIO readFile(pathFileName, FileIO::ByteOrder::LittleEndian, FileIO::Mode::ReadOnly, FileIO::CreationFlags::None);
if(!readFile.isOkay())
{
std::cout << "File open failed " << pathFileName << std::endl;
return false;
}
readFile.setBufferLength(BUFFER_LENGTH);
DWORD fileLength = readFile.size();
sendPutIndicator(pathFileName, fileLength);
Array<char> readBuffer;
readBuffer.size(BUFFER_LENGTH);
std::cout << "Sending file " << pathFileName << " " << Utility::byteCountToString(fileLength, false) << std::endl;
while(true)
{
size_t bytesRead = readFile.read(&readBuffer[0], readBuffer.size());
if(0==bytesRead)
{
std::cout << "No data was read from the file" << std::endl;
break;
}
sendPacketIndicator(bytesRead);
sendPacket(readBuffer, bytesRead);
if(bytesRead<readBuffer.size())break;
}
sendPacketIndicator(0);
sendQuit();
readFile.close();
std::cout << "SendFile done, total took " << profiler.end() << "(ms)" << std::endl;
return true;
}
/// @brief Send PCKT with length of packet
/// @param bytesToSend
/// @return
bool ClientSocketSender::sendPacketIndicator(DWORD bytesToSend)
{
if(!isOkay())return false;
String packetIndicator = "PCKT|";
packetIndicator+=String().fromULong(bytesToSend);
packetIndicator+="\r\n";
::send(mSocket, (char*)packetIndicator, packetIndicator.length(),0);
return true;
}
/// @brief Send PUT with filename and file length
/// @param fileName
/// @param fileLength
/// @return
bool ClientSocketSender::sendPutIndicator(String fileName,DWORD fileLength)
{
if(!isOkay())return false;
Block<String> parts = fileName.split('/');
String pureFileName = parts[parts.size()-1];
String putIndicator = "PUT|";
putIndicator+=pureFileName;
putIndicator+="|";
putIndicator+=String().fromULong(fileLength);
putIndicator+="\r\n";
::send(mSocket, (char*)putIndicator, putIndicator.length(),0);
return true;
}
/// @brief Send QUIT
/// @param
/// @return
bool ClientSocketSender::sendQuit(void)
{
if(!isOkay())return false;
String quitIndicator = "QUIT\r\n";
::send(mSocket, (char*)quitIndicator, quitIndicator.length(),0);
return true;
}
/// @brief items in buffer with length bytesToSend
/// @param buffer The buffer to send
/// @param bytesToSend The number of bytes to send
/// @return
bool ClientSocketSender::sendPacket(Array<char> &buffer,DWORD bytesToSend)
{
if(!isOkay())return false;
::send(mSocket, (char*)&buffer[0], bytesToSend,0);
return true;
}
bool ClientSocketSender::isOkay(void)
{
return -1==mSocket?false:true;
}