150 lines
4.3 KiB
C++
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;
|
|
}
|