1200 lines
36 KiB
C++
1200 lines
36 KiB
C++
#include "FtsdSocketControl.h"
|
|
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
#include <iterator>
|
|
|
|
// NEW 2016-05-12 huibong data 수신 실패시 timeout 처리 관련 기능 추가.
|
|
#define FTSD_DATA_RECV_TIMEOUT 2 //sec ( 3 sec 이상일 경우.. Alive check 와 충돌로 timeout 처리가 안 될 수 있음.)
|
|
|
|
|
|
/// @brief 생성자.
|
|
CFtsdSocketControl::CFtsdSocketControl( )
|
|
: CBaseSocket( SOCKET_NOT_VALID )
|
|
, m_nPacketHeaderLen ( sizeof(m_packetHeader))
|
|
, m_nPacketDataLen( 0 )
|
|
{
|
|
}
|
|
|
|
/// @brief 소멸자
|
|
CFtsdSocketControl::~CFtsdSocketControl()
|
|
{
|
|
// 소멸자 Socket 명시적 Close 처리.
|
|
Close();
|
|
}
|
|
|
|
/// @brief 전달받은 Target 으로 Socket 접속을 수행
|
|
/// @param szTarget [in] 접속 대상 Host name 또는 IP
|
|
/// @param nPort [in] 접속 Port
|
|
/// @return 접속 성공시 true, 실패시 false 반환. ( 오류 내역은 로깅처리됨.)
|
|
bool CFtsdSocketControl::ConnectTarget( const std::string& szTarget, int nPort )
|
|
{
|
|
return Connect( szTarget, nPort );
|
|
}
|
|
|
|
|
|
/// @brief Packet Header 정보를 Log 파일에 Logging 처리
|
|
void CFtsdSocketControl::PrintHeaderToLog()
|
|
{
|
|
|
|
_LOG( LINF, "------------------------------------" );
|
|
_LOG( LINF, "stx [%02x]", m_packetHeader.stx );
|
|
_LOG( LINF, "type [%02x]", m_packetHeader.type );
|
|
_LOG( LINF, "command [%02x][%02x][%02x][%02x]" , m_packetHeader.command[0], m_packetHeader.command[1] , m_packetHeader.command[2], m_packetHeader.command[3] );
|
|
_LOG( LINF, "result [%02x][%02x][%02x][%02x]" , m_packetHeader.result[0], m_packetHeader.result[1] , m_packetHeader.result[2], m_packetHeader.result[3] );
|
|
_LOG( LINF, "data_length [%u]", m_nPacketDataLen );
|
|
_LOG( LINF, "extend_code [%02x][%02x]", m_packetHeader.extend_code[0], m_packetHeader.extend_code[1] );
|
|
|
|
_LOG( LINF, "------------------------------------" );
|
|
}
|
|
|
|
|
|
/// @brief Alive Check 를 위한 패킷 전송 => 해당 패킷의 응답은 필요없으므로 수신시 무시할 것.
|
|
/// @return 전송 성공시 true, 실패시 false 반환.
|
|
bool CFtsdSocketControl::SendAliveCheck()
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
// 정보 요청을 위한 Packet Header 생성.
|
|
struct FileTransferPacketHeader stHeader;
|
|
memset(&stHeader, 0x00, sizeof(struct FileTransferPacketHeader));
|
|
|
|
stHeader.stx = HEADER_STX_CODE;
|
|
stHeader.type = HEADER_TYPE_REQUEST;
|
|
stHeader.command[0] = COMMON_ALIVE_CHECK;
|
|
|
|
// Packet Header 정보 전송
|
|
if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/// @brief 연결된 Socket 을 통해 Transfer Daemon 으로 File Replication 명령 전송.
|
|
/// @param szFileName [in] 복제할 원본 Source 파일명
|
|
/// @param nFileSize [in] 복제할 원본 Source 파일의 크기.
|
|
/// @param szTargetTranId [in[ RC 간 복제 처리시 변경할 대상 Tran ID 정보 값
|
|
/// @param nFileHashCheckLevel [in] File 에 대한 Hash Check Level 정보
|
|
/// @param bUseInternalIp [in] 내부망을 이용하여 파일 송수신을 수행할지 여부
|
|
/// @param vecTargetFhs [in] 복제할 Target FHS 정보
|
|
/// @return Replication 복제 요청 메시지 전송 성공시 true, 실패시 false 반환.
|
|
bool CFtsdSocketControl::SendFileReplicationRequest(const std::string& szFileName, unsigned long long nFileSize
|
|
, int nFileHashCheckLevel, bool bUseInternalIp, std::vector< std::string >& vecTargetFhs)
|
|
{
|
|
std::string szTargetTranId;
|
|
szTargetTranId.clear();
|
|
|
|
return SendFileReplicationRequest( szFileName, nFileSize, szTargetTranId, nFileHashCheckLevel, bUseInternalIp, vecTargetFhs);
|
|
}
|
|
|
|
bool CFtsdSocketControl::SendFileReplicationRequest(const std::string& szFileName, unsigned long long nFileSize
|
|
, const std::string& szTargetTranId, int nFileHashCheckLevel, bool bUseInternalIp, std::vector< std::string >& vecTargetFhs)
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
// 정보 요청을 위한 Packet Header 생성.
|
|
struct FileTransferPacketHeader stHeader;
|
|
memset(&stHeader, 0x00, sizeof(struct FileTransferPacketHeader));
|
|
|
|
stHeader.stx = HEADER_STX_CODE;
|
|
stHeader.type = HEADER_TYPE_REQUEST;
|
|
stHeader.command[0] = CONTROL_FILE_REPLICATION;
|
|
|
|
// Data 부분의 길이를 계산한다.
|
|
unsigned int nTemp = 0;
|
|
|
|
nTemp = 4 + szFileName.size(); // File Name ( 4 + 가변 )
|
|
nTemp += 8; // File Size ( 8 Byte )
|
|
nTemp += ( 4 + szTargetTranId.size()); // Target Tran ID ( 4 + 가변 )
|
|
nTemp += 4; // File Hash check Level ( 4 Byte )
|
|
nTemp += 1; // 내부망 IP 사용 여부 ( 1 Byte )
|
|
nTemp += 4; // FHS Count ( 4 Byte )
|
|
|
|
std::vector< std::string >::const_iterator it;
|
|
for( it = vecTargetFhs.begin(); it != vecTargetFhs.end() ; it++ )
|
|
{
|
|
nTemp = nTemp + 4 + it->size() ; // Target FHS 정보 ( 4 + 가변 )
|
|
}
|
|
|
|
stHeader.data_length = htonl( nTemp );
|
|
|
|
// Packet Header 정보 전송
|
|
if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen )
|
|
{
|
|
LOG( LERR, "File Replication request send failed.");
|
|
|
|
return false;
|
|
}
|
|
|
|
// Packet Data 부분 전송
|
|
|
|
// File Name 부분
|
|
nTemp = htonl( szFileName.size() );
|
|
WriteN( &nTemp, 4);
|
|
WriteN( szFileName.c_str(), szFileName.size() );
|
|
|
|
// File Size 전송
|
|
WriteN( &nFileSize, 8 );
|
|
|
|
// Target Tran ID 부분
|
|
nTemp = htonl( szTargetTranId.size() );
|
|
WriteN( &nTemp, 4);
|
|
if( szTargetTranId.size() > 0 )
|
|
WriteN( szTargetTranId.c_str(), szTargetTranId.size() );
|
|
|
|
// File Hash Check Level 전송
|
|
nTemp = htonl( nFileHashCheckLevel );
|
|
WriteN( &nTemp, 4);
|
|
|
|
// 내부망 사용 여부 전달
|
|
if( bUseInternalIp == true )
|
|
m_tempBuffer[0] = 0x01;
|
|
else
|
|
m_tempBuffer[0] = 0x00;
|
|
|
|
WriteN( m_tempBuffer, 1);
|
|
|
|
// Target FHS Count 정보 전달.
|
|
nTemp = htonl( vecTargetFhs.size() );
|
|
WriteN( &nTemp, 4);
|
|
|
|
// Loop 를 돌면서 각 FHS 정보를 전달한다.
|
|
for( it = vecTargetFhs.begin(); it != vecTargetFhs.end() ; it++ )
|
|
{
|
|
nTemp = htonl( it->size() );
|
|
WriteN( &nTemp, 4);
|
|
WriteN( it->c_str(), it->size());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/// @brief File Replication 요청에 대한 처리 결과를 수신한다.
|
|
/// @param nTimeout [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값.
|
|
/// @param bSuccess [out] File Replication 이 정상적으로 수행되었는지 여부
|
|
/// @param szErrorMessage [out] bSuccess == false 인 경우 발생된 오류메시지 정보.
|
|
/// @param mapSuccessFhs [out] Replication 에 대한 처리 성공시 성공한 FHS 및 File 정보를 저장
|
|
/// @param mapFailFhs [out] Replication 에 대한 처리 성공시 실패한 FHS 및 오류메시지 정보를 저장.
|
|
/// @return -1 : Read 수신시 오류 발생시 => ftsd 와 연결이 끝어진것으로 판단하고 오류처리한다. \n
|
|
///< 0 : nTimeout 에 지정된 시간안에 완료 응답을 받지 못한 경우. \n
|
|
///< 이 기능은 호출 함수의 Block 을 해제하기 위한 기능으로 \n
|
|
///< 이 값이 반환된 경우 다른 작업을 한 후 다시 호출하도록 한다. \n
|
|
///< 1 : 파일 복제 처리에 대한 응답을 수신한 경우, Output 인자를 확인할 것. \n
|
|
///< 2 : Transfer Daemon 으로 부터 Packet 을 수신하였으나 File Replication 요청에 대한 응답이 아닌 경우 \n
|
|
///< 해당 정보는 멤버변수 상에 저장된다. ( 단 Alive Packet 은 아님)
|
|
int CFtsdSocketControl::GetFileReplicationResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage
|
|
, std::map< std::string, std::string>& mapSuccessFhs
|
|
, std::map< std::string, std::string>& mapFailFhs )
|
|
{
|
|
// 복제 요청에 대한 응답 패킷 대기
|
|
// 수신 대기 Timeout 은 전달받은 값으로 설정.
|
|
if( IsValidSocket() == false )
|
|
return -1;
|
|
|
|
int nRead;
|
|
bool isAlivePacket;
|
|
do
|
|
{
|
|
isAlivePacket = false;
|
|
|
|
// Socket 으로 부터 Packet Header 부분 수신.
|
|
// 수신된 정보는 멤버변수에 저장처리.
|
|
nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout );
|
|
|
|
// nRead 0: Socket Closed, -1: error , -2: Timeout 이므로
|
|
if( nRead == -2 )
|
|
return 0; // Timeout 반환.
|
|
else if( nRead == 0 || nRead == -1 )
|
|
return -1; // Socket Close 또는 오류 발생시
|
|
|
|
// STX code 검사.
|
|
if( m_packetHeader.stx != HEADER_STX_CODE )
|
|
{
|
|
LOG( LERR, "Not valid stx code.");
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Data Length 부분 값을 멤버 변수에 저장처리.
|
|
m_nPacketDataLen = ntohl( m_packetHeader.data_length );
|
|
|
|
// Alive Check Packet 인 경우 해당 패킷은 무시처리 후 다시 수신 처리한다.
|
|
if( m_packetHeader.type == HEADER_TYPE_REQUEST
|
|
&& m_packetHeader.command[0] == COMMON_ALIVE_CHECK
|
|
&& m_nPacketDataLen == 0 )
|
|
{
|
|
isAlivePacket = true;
|
|
}
|
|
|
|
} while( isAlivePacket == true );
|
|
|
|
// Alive Packet 이 아닌 경우 해당 Packet 에 대한 복제에 대한 응답패킷인지 검사.
|
|
if( m_packetHeader.type != HEADER_TYPE_RESPONSE
|
|
|| m_packetHeader.command[0] != CONTROL_FILE_REPLICATION )
|
|
{
|
|
// 다른 패킷이 들어온 경우
|
|
|
|
// ** 정석대로라면 그냥 냅둬어 수신부에서 처리해야 하지만
|
|
// 현재 수신 처리부가 없어 당장 문제가 생길수 있으므로
|
|
// 데이터 부분까지 수신하여 임시버퍼에 저장처리 해 놓는다.
|
|
GetPacketData( m_nPacketDataLen );
|
|
return 2;
|
|
}
|
|
|
|
// Replication 에 대한 응답 패킷인 경우
|
|
|
|
// 1. 성공, 실패 여부 판단.
|
|
if( m_packetHeader.result[0] != HEADER_RESULT_SUCCESS )
|
|
{
|
|
// 오류가 발생한 경우임
|
|
bSuccess = false;
|
|
|
|
// Packet Data 상에서 오류 메시지를 수신받아 반환 처리.
|
|
if( GetPacketData( m_nPacketDataLen, szErrorMessage ) == false )
|
|
{
|
|
LOG( LERR, "Error msg receive failed.");
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
// 2. 성공인 경우
|
|
bSuccess = true;
|
|
|
|
unsigned int nCount;
|
|
unsigned int nLength;
|
|
std::string szKey;
|
|
std::string szValue;
|
|
|
|
// 2.1 성공 목록의 Count 정보 수신
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "Success count receive failed.");
|
|
return -1;
|
|
}
|
|
nCount = GetDataToUInt( m_tempBuffer, true);
|
|
for( unsigned int i = 0; i < nCount; i++)
|
|
{
|
|
szKey.clear();
|
|
szValue.clear();
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szKey );
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szValue );
|
|
|
|
mapSuccessFhs[ szKey ] = szValue;
|
|
}
|
|
|
|
// 2.2 실패 목록의 Count 정보 수신
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "Failed count receive failed.");
|
|
return -1;
|
|
}
|
|
nCount = GetDataToUInt( m_tempBuffer, true);
|
|
for( unsigned int i = 0; i < nCount; i++)
|
|
{
|
|
szKey.clear();
|
|
szValue.clear();
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szKey );
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szValue );
|
|
|
|
mapFailFhs[ szKey ] = szValue;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/// @brief 대상과 연결된 Socket 을 통해 Transfer Daemon 으로 File Cache 명령 전송.
|
|
/// @param szFileName [in] Cache 처리할 원본 Source 파일명 (/stg/node0/186/abcde..)
|
|
/// @param nFileSize [in] Cache 처리할 원본 Source 파일의 크기.
|
|
/// @param nFileHashCheckLevel [in] File 에 대한 Hash Check Level 정보 ( conf 파일에 지정됨)
|
|
/// @param bUseInternalIp [in] 내부망을 이용하여 파일 송수신을 수행할지 여부 \n
|
|
///< 해당값을 true 로 지정시 ftsd 상에서 내부망을 우선 사용하여 파일 복제 시도
|
|
///< 만약 내부망 사용 불가시 자동으로 외부망 사용.
|
|
/// @param vecTargetFhs [in] Cache 대상 Target FHS Host Name 정보
|
|
/// @return Cache 요청 메시지 전송 성공시 true, 실패시 false 반환.
|
|
bool CFtsdSocketControl::SendFileCacheRequest(const std::string& szFileName, unsigned long long nFileSize
|
|
, int nFileHashCheckLevel, bool bUseInternalIp, std::vector< std::string >& vecTargetFhs)
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
// 정보 요청을 위한 Packet Header 생성.
|
|
struct FileTransferPacketHeader stHeader;
|
|
memset(&stHeader, 0x00, sizeof(struct FileTransferPacketHeader));
|
|
|
|
stHeader.stx = HEADER_STX_CODE;
|
|
stHeader.type = HEADER_TYPE_REQUEST;
|
|
stHeader.command[0] = CONTROL_FILE_CACHE;
|
|
|
|
// Data 부분의 길이를 계산한다.
|
|
unsigned int nTemp = 0;
|
|
|
|
nTemp = 4 + szFileName.size(); // File Name ( 4 + 가변 )
|
|
nTemp += 8; // File Size ( 8 Byte )
|
|
nTemp += 4; // Target Tran ID ( 4 + 실제값은 사용 안하므로 0 )
|
|
nTemp += 4; // File Hash check Level ( 4 Byte )
|
|
nTemp += 1; // 내부망 IP 사용 여부 ( 1 Byte )
|
|
nTemp += 4; // FHS Count ( 4 Byte )
|
|
|
|
std::vector< std::string >::const_iterator it;
|
|
for( it = vecTargetFhs.begin(); it != vecTargetFhs.end() ; it++ )
|
|
{
|
|
nTemp = nTemp + 4 + it->size() ; // Target FHS 정보 ( 4 + 가변 )
|
|
}
|
|
|
|
stHeader.data_length = htonl( nTemp );
|
|
|
|
// Packet Header 정보 전송
|
|
if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen )
|
|
{
|
|
LOG( LERR, "File Cache request send failed.");
|
|
return false;
|
|
}
|
|
|
|
// Packet Data 부분 전송
|
|
|
|
// File Name 부분
|
|
nTemp = htonl( szFileName.size() );
|
|
WriteN( &nTemp, 4);
|
|
WriteN( szFileName.c_str(), szFileName.size() );
|
|
|
|
// File Size 전송
|
|
WriteN( &nFileSize, 8 );
|
|
|
|
// Target Tran ID 부분
|
|
nTemp = htonl( 0 );
|
|
WriteN( &nTemp, 4);
|
|
|
|
// File Hash Check Level 전송
|
|
nTemp = htonl( nFileHashCheckLevel );
|
|
WriteN( &nTemp, 4);
|
|
|
|
// 내부망 사용 여부 전달
|
|
if( bUseInternalIp == true )
|
|
m_tempBuffer[0] = 0x01;
|
|
else
|
|
m_tempBuffer[0] = 0x00;
|
|
|
|
WriteN( m_tempBuffer, 1);
|
|
|
|
// Target FHS Count 정보 전달.
|
|
nTemp = htonl( vecTargetFhs.size() );
|
|
WriteN( &nTemp, 4);
|
|
|
|
// Loop 를 돌면서 각 FHS 정보를 전달한다.
|
|
for( it = vecTargetFhs.begin(); it != vecTargetFhs.end() ; it++ )
|
|
{
|
|
nTemp = htonl( it->size() );
|
|
WriteN( &nTemp, 4);
|
|
WriteN( it->c_str(), it->size());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// @brief File Cache 요청에 대한 처리 결과를 transfer daemon 으로 부터 수신한다.
|
|
/// @param nTimeout [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값. 단위( second )\n
|
|
///< 지정된 시간동안 응답을 수신하지 못한 경우 0 을 반환.
|
|
/// @param bSuccess [out] File Cache 처리가 정상적으로 수행되었는지 여부 \n
|
|
///< trnsfer 상에서 오류가 발생한 경우 이 값은 false 가 되며 \n
|
|
///< szErrorMessage 변수상에 오류내용이 저장됨. \n
|
|
///< 정상적으로 처리된 경우 true 가 저장되며 \n
|
|
///< mapSuccessFhs, mapFailFhs 상에 관련 정보가 저장됨.
|
|
/// @param szErrorMessage [out] bSuccess == false 인 경우 발생된 오류메시지 정보를 저장
|
|
/// @param mapSuccessFhs [out] bSuccess == true 인 경우 \n
|
|
///< Cache 처리에 성공한 FHS 및 저장된 File 이름 정보를 저장
|
|
/// @param mapFailFhs [out] bSuccess == true 인 경우 \n
|
|
///< Cache 처리에 실패한 FHS Host Name 및 발생된 오류메시지 정보를 저장.
|
|
/// @return -1 : Socket 통신 관련 오류 발생하여 Transfer Daemon 과 연결이 끊어진 경우 \n
|
|
///< => ftsd 와 연결이 끝어진것으로 판단하고 오류처리한다. \n
|
|
///< 0 : 입력변수인 nTimeout 에 지정된 시간안에 Transfer Daemon으로부터
|
|
///< Cache 에 대한 처리 결과 정보를 수신하지 못한 경우. \n
|
|
///< 이 기능은 본 함수 호출시 Blocking 발생을 막기 위한 기능으로서 \n
|
|
///< 이 값이 반환된 경우 추가 다른 작업을 진행한 후 본 함수를 다시 호출하여 \n
|
|
///< 응답을 대기할 수 있다. \n
|
|
///< 1 : 파일 Cache 처리에 대한 응답을 수신한 경우, Output 인자인 bSuccess 를 확인하여 처리 결과 확인
|
|
///< 2 : Transfer Daemon 으로 부터 Data 을 수신하였으나 File Cache 요청에 대한 응답이 아닌 경우 \n
|
|
///< 해당 정보는 본 클래스의 멤버변수 상에 내부적으로 저장된다. ( 단 Alive Packet 은 아님) \n
|
|
///< 본 결과가 수신된 경우 무시 처리하고 계속 응답을 대기하면 된다.
|
|
int CFtsdSocketControl::GetFileCacheResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage
|
|
, std::map< std::string, std::string>& mapSuccessFhs
|
|
, std::map< std::string, std::string>& mapFailFhs )
|
|
{
|
|
// Cache 처리 요청에 대한 응답 패킷 대기
|
|
// 수신 대기 Timeout 은 전달받은 값으로 설정.
|
|
if( IsValidSocket() == false )
|
|
return -1;
|
|
|
|
int nRead;
|
|
bool isAlivePacket;
|
|
do
|
|
{
|
|
isAlivePacket = false;
|
|
|
|
// Socket 으로 부터 Packet Header 부분 수신.
|
|
// 수신된 정보는 멤버변수에 저장처리.
|
|
nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout );
|
|
|
|
// nRead 0: Socket Closed, -1: error , -2: Timeout 이므로
|
|
if( nRead == -2 )
|
|
return 0; // Timeout 반환.
|
|
else if( nRead == 0 || nRead == -1 )
|
|
return -1; // Socket Close 또는 오류 발생시
|
|
|
|
// STX code 검사.
|
|
if( m_packetHeader.stx != HEADER_STX_CODE )
|
|
{
|
|
LOG( LERR, "Not valid stx code.");
|
|
return -1;
|
|
}
|
|
|
|
// Data Length 부분 값을 멤버 변수에 저장처리.
|
|
m_nPacketDataLen = ntohl( m_packetHeader.data_length );
|
|
|
|
// Alive Check Packet 인 경우 해당 패킷은 무시처리 후 다시 수신 처리한다.
|
|
if( m_packetHeader.type == HEADER_TYPE_REQUEST
|
|
&& m_packetHeader.command[0] == COMMON_ALIVE_CHECK
|
|
&& m_nPacketDataLen == 0 )
|
|
{
|
|
isAlivePacket = true;
|
|
}
|
|
|
|
} while( isAlivePacket == true );
|
|
|
|
// Alive Packet 이 아닌 경우 해당 Packet 에 대한 Cache 처리 요청에 대한 응답패킷인지 검사.
|
|
if( m_packetHeader.type != HEADER_TYPE_RESPONSE
|
|
|| m_packetHeader.command[0] != CONTROL_FILE_CACHE )
|
|
{
|
|
// 다른 패킷이 들어온 경우
|
|
|
|
// ** 정석대로라면 그냥 냅둬어 수신부에서 처리해야 하지만
|
|
// 현재 수신 처리부가 없어 당장 문제가 생길수 있으므로
|
|
// 데이터 부분까지 수신하여 임시버퍼에 저장처리 해 놓는다.
|
|
GetPacketData( m_nPacketDataLen );
|
|
return 2;
|
|
}
|
|
|
|
// Cache 요청에 대한 응답 패킷인 경우
|
|
|
|
// 1. 성공, 실패 여부 판단.
|
|
if( m_packetHeader.result[0] != HEADER_RESULT_SUCCESS )
|
|
{
|
|
// 오류가 발생한 경우임
|
|
bSuccess = false;
|
|
|
|
// Packet Data 상에서 오류 메시지를 수신받아 반환 처리.
|
|
if( GetPacketData( m_nPacketDataLen, szErrorMessage ) == false )
|
|
{
|
|
LOG( LERR, "Error msg receive failed.");
|
|
return -1;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
// 2. 성공인 경우
|
|
bSuccess = true;
|
|
|
|
unsigned int nCount;
|
|
unsigned int nLength;
|
|
std::string szKey;
|
|
std::string szValue;
|
|
|
|
// 2.1 성공 목록의 Count 정보 수신
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "Success count receive failed.");
|
|
return -1;
|
|
}
|
|
nCount = GetDataToUInt( m_tempBuffer, true);
|
|
for( unsigned int i = 0; i < nCount; i++)
|
|
{
|
|
szKey.clear();
|
|
szValue.clear();
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szKey );
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szValue );
|
|
|
|
mapSuccessFhs[ szKey ] = szValue;
|
|
}
|
|
|
|
// 2.2 실패 목록의 Count 정보 수신
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "Failed count receive failed.");
|
|
return -1;
|
|
}
|
|
nCount = GetDataToUInt( m_tempBuffer, true);
|
|
for( unsigned int i = 0; i < nCount; i++)
|
|
{
|
|
szKey.clear();
|
|
szValue.clear();
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szKey );
|
|
|
|
GetPacketData( 4 );
|
|
nLength = GetDataToUInt( m_tempBuffer, true);
|
|
GetPacketData( nLength, szValue );
|
|
|
|
mapFailFhs[ szKey ] = szValue;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 Content Check 명령 전송.
|
|
bool CFtsdSocketControl::SendFileCheckRequest(const std::string& szFileName, bool bHashCheck, unsigned long long nHashCheckSize )
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
// 정보 요청을 위한 Packet Header 생성.
|
|
struct FileTransferPacketHeader stHeader;
|
|
memset(&stHeader, 0x00, sizeof(struct FileTransferPacketHeader));
|
|
|
|
stHeader.stx = HEADER_STX_CODE;
|
|
stHeader.type = HEADER_TYPE_REQUEST;
|
|
stHeader.command[0] = CONTROL_FILE_CHECK;
|
|
|
|
// Data 부분의 길이를 계산한다.
|
|
unsigned int nTemp = 0;
|
|
|
|
nTemp = 4 + szFileName.size(); // File Name ( 4 + 가변 )
|
|
nTemp += 4; // File Hash 추출 여부 ( 4 Byte )
|
|
|
|
if( bHashCheck == true )
|
|
{
|
|
nTemp += 8; // File Hash 추출 Size 정보 ( 8 Byte )
|
|
}
|
|
|
|
stHeader.data_length = htonl( nTemp );
|
|
|
|
// Packet Header 정보 전송
|
|
if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen )
|
|
{
|
|
LOG( LERR, "File[%s] Check request send failed.", szFileName.c_str() );
|
|
return false;
|
|
}
|
|
|
|
// Packet Data 부분 전송
|
|
|
|
// 1. File Name 부분
|
|
nTemp = htonl( szFileName.size() );
|
|
WriteN( &nTemp, 4);
|
|
WriteN( szFileName.c_str(), szFileName.size() );
|
|
|
|
// 2. Hash 추출 여부
|
|
if( bHashCheck == true )
|
|
{
|
|
nTemp = htonl( 1 );
|
|
WriteN( &nTemp, 4);
|
|
|
|
// 3. Hash 추출 size (MByte 단위 ) 값 전송.
|
|
WriteN( &nHashCheckSize, 8 );
|
|
}
|
|
else
|
|
{
|
|
nTemp = htonl( 0 );
|
|
WriteN( &nTemp, 4);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 Unlink 명령 전송.
|
|
bool CFtsdSocketControl::SendFileUnlinkRequest(const std::string& szFileName, unsigned long long nFileSize, bool bForceUnlink )
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
// 정보 요청을 위한 Packet Header 생성.
|
|
struct FileTransferPacketHeader stHeader;
|
|
memset(&stHeader, 0x00, sizeof(struct FileTransferPacketHeader));
|
|
|
|
stHeader.stx = HEADER_STX_CODE;
|
|
stHeader.type = HEADER_TYPE_REQUEST;
|
|
stHeader.command[0] = CONTROL_FILE_UNLINK;
|
|
|
|
// Data 부분의 길이를 계산한다.
|
|
unsigned int nTemp = 0;
|
|
|
|
nTemp = 4 + szFileName.size(); // File Name ( 4 + 가변 )
|
|
nTemp += 8; // File Size ( 8 Byte )
|
|
nTemp += 4; // Unlink Mode ( 4 Byte )
|
|
|
|
stHeader.data_length = htonl( nTemp );
|
|
|
|
// Packet Header 정보 전송
|
|
if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen )
|
|
{
|
|
LOG( LERR, "File[%s] Unlink request send failed.", szFileName.c_str() );
|
|
return false;
|
|
}
|
|
|
|
// Packet Data 부분 전송
|
|
|
|
// 1. File Name 부분
|
|
nTemp = htonl( szFileName.size() );
|
|
WriteN( &nTemp, 4);
|
|
WriteN( szFileName.c_str(), szFileName.size() );
|
|
|
|
// 2. File Size 부분
|
|
WriteN( &nFileSize, 8 );
|
|
|
|
// 3. Unlink Mode 정보
|
|
if( bForceUnlink == true )
|
|
{
|
|
nTemp = htonl( UNLINK_MODE_FORCE );
|
|
}
|
|
else
|
|
{
|
|
nTemp = htonl( UNLINK_MODE_NORMAL );
|
|
}
|
|
WriteN( &nTemp, 4);
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
/// @brief File Check 요청에 대한 처리 결과를 ftsd 로 부터 수신한다.
|
|
int CFtsdSocketControl::GetFileCheckResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage, unsigned long long& nFileSize, std::string& szHashValue )
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return -1;
|
|
|
|
int nRead;
|
|
bool isAlivePacket;
|
|
do
|
|
{
|
|
isAlivePacket = false;
|
|
|
|
// Socket 으로 부터 Packet Header 부분 수신.
|
|
// 수신된 정보는 멤버변수에 저장처리.
|
|
nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout );
|
|
|
|
// nRead 0: Socket Closed, -1: error , -2: Timeout 이므로
|
|
if( nRead == -2 )
|
|
return 0; // Timeout 반환.
|
|
else if( nRead == 0 || nRead == -1 )
|
|
return -1; // Socket Close 또는 오류 발생시
|
|
|
|
// STX code 검사.
|
|
if( m_packetHeader.stx != HEADER_STX_CODE )
|
|
{
|
|
LOG( LERR, "Not valid stx code.");
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Data Length 부분 값을 멤버 변수에 저장처리.
|
|
m_nPacketDataLen = ntohl( m_packetHeader.data_length );
|
|
|
|
// Alive Check Packet 인 경우 해당 패킷은 무시처리 후 다시 수신 처리한다.
|
|
if( m_packetHeader.type == HEADER_TYPE_REQUEST
|
|
&& m_packetHeader.command[0] == COMMON_ALIVE_CHECK
|
|
&& m_nPacketDataLen == 0 )
|
|
{
|
|
isAlivePacket = true;
|
|
}
|
|
|
|
} while( isAlivePacket == true );
|
|
|
|
// Alive Packet 이 아닌 경우 해당 Packet 에 대한 Check에 대한 응답 패킷인지 검사.
|
|
if( m_packetHeader.type != HEADER_TYPE_RESPONSE
|
|
|| m_packetHeader.command[0] != CONTROL_FILE_CHECK )
|
|
{
|
|
// 다른 패킷이 들어온 경우
|
|
|
|
// ** 정석대로라면 그냥 냅둬어 수신부에서 처리해야 하지만
|
|
// 현재 수신 처리부가 없어 당장 문제가 생길수 있으므로
|
|
// 데이터 부분까지 수신하여 임시버퍼에 저장처리 해 놓는다.
|
|
GetPacketData( m_nPacketDataLen );
|
|
return 2;
|
|
}
|
|
|
|
// Check 에 대한 응답 패킷이 경우.
|
|
|
|
// 1. 성공, 실패 여부 판단.
|
|
if( m_packetHeader.result[0] != HEADER_RESULT_SUCCESS )
|
|
{
|
|
// 오류가 발생한 경우임
|
|
bSuccess = false;
|
|
|
|
// Packet Data 상에서 오류 메시지를 수신받아 반환 처리.
|
|
if( GetPacketData( m_nPacketDataLen, szErrorMessage ) == false )
|
|
{
|
|
LOG( LERR, "Error msg receive failed.");
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
// 2. 성공인 경우
|
|
bSuccess = true;
|
|
|
|
// 2.1 File Size 정보 추출..
|
|
if( GetPacketData( 8 ) == false )
|
|
{
|
|
LOG( LERR, "File size receive fail.");
|
|
return -1;
|
|
}
|
|
nFileSize = GetDataToUInt64( m_tempBuffer );
|
|
|
|
// 2.2 File Hash 필드의 Length 정보 추출.
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "Hash length receive fail.");
|
|
return -1;
|
|
}
|
|
|
|
unsigned int nLength = GetDataToUInt( m_tempBuffer, true);
|
|
|
|
if( nLength > 0 )
|
|
{
|
|
// 추출된 Hash 정보 저장.
|
|
GetPacketData( nLength, szHashValue );
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/// @brief File Unlink 요청에 대한 처리 결과를 ftsd 로 부터 수신한다.
|
|
int CFtsdSocketControl::GetFileUnlinkResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage )
|
|
{
|
|
|
|
if( IsValidSocket() == false )
|
|
return -1;
|
|
|
|
int nRead;
|
|
bool isAlivePacket;
|
|
do
|
|
{
|
|
isAlivePacket = false;
|
|
|
|
// Socket 으로 부터 Packet Header 부분 수신.
|
|
// 수신된 정보는 멤버변수에 저장처리.
|
|
nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout );
|
|
|
|
// nRead 0: Socket Closed, -1: error , -2: Timeout 이므로
|
|
if( nRead == -2 )
|
|
return 0; // Timeout 반환.
|
|
else if( nRead == 0 || nRead == -1 )
|
|
return -1; // Socket Close 또는 오류 발생시
|
|
|
|
// STX code 검사.
|
|
if( m_packetHeader.stx != HEADER_STX_CODE )
|
|
{
|
|
LOG( LERR, "Not valid stx code.");
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Data Length 부분 값을 멤버 변수에 저장처리.
|
|
m_nPacketDataLen = ntohl( m_packetHeader.data_length );
|
|
|
|
// Alive Check Packet 인 경우 해당 패킷은 무시처리 후 다시 수신 처리한다.
|
|
if( m_packetHeader.type == HEADER_TYPE_REQUEST
|
|
&& m_packetHeader.command[0] == COMMON_ALIVE_CHECK
|
|
&& m_nPacketDataLen == 0 )
|
|
{
|
|
isAlivePacket = true;
|
|
}
|
|
|
|
} while( isAlivePacket == true );
|
|
|
|
// Alive Packet 이 아닌 경우 해당 Packet 에 대한 Unlink 에 대한 응답 패킷인지 검사.
|
|
if( m_packetHeader.type != HEADER_TYPE_RESPONSE
|
|
|| m_packetHeader.command[0] != CONTROL_FILE_UNLINK )
|
|
{
|
|
// 다른 패킷이 들어온 경우
|
|
|
|
// ** 정석대로라면 그냥 냅둬어 수신부에서 처리해야 하지만
|
|
// 현재 수신 처리부가 없어 당장 문제가 생길수 있으므로
|
|
// 데이터 부분까지 수신하여 임시버퍼에 저장처리 해 놓는다.
|
|
GetPacketData( m_nPacketDataLen );
|
|
return 2;
|
|
}
|
|
|
|
// Unlink 에 대한 응답 패킷이 경우.
|
|
|
|
// 1. 성공, 실패 여부 판단.
|
|
if( m_packetHeader.result[0] != HEADER_RESULT_SUCCESS )
|
|
{
|
|
// 오류가 발생한 경우임
|
|
bSuccess = false;
|
|
|
|
// Packet Data 상에서 오류 메시지를 수신받아 반환 처리.
|
|
if( GetPacketData( m_nPacketDataLen, szErrorMessage ) == false )
|
|
{
|
|
LOG( LERR, "Error msg receive failed.");
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
// 2. 성공인 경우
|
|
bSuccess = true;
|
|
|
|
// 2.1 성공인 경우 Data 부분이 존재하지 않으므로.. Pass..
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
// NEW 2016-05-04 huibong 토토디스크 지원용 기능 추가 (#27460)
|
|
/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 Content Check 명령 전송. (토토디스크 지원용)
|
|
/// @param szFileName [in] 원본 Source 파일명 (/stg/node0/186/abcde..)
|
|
/// @return Check 요청 메시지 전송 성공시 true, 실패시 false 반환.
|
|
bool CFtsdSocketControl::SendFileCheckTOTORequest( const std::string& szFileName )
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
// 정보 요청을 위한 Packet Header 생성.
|
|
struct FileTransferPacketHeader stHeader;
|
|
memset( &stHeader, 0x00, sizeof( struct FileTransferPacketHeader ) );
|
|
|
|
stHeader.stx = HEADER_STX_CODE;
|
|
stHeader.type = HEADER_TYPE_REQUEST;
|
|
stHeader.command[0] = CONTROL_FILE_CHECK_TOTO;
|
|
|
|
// Data 부분의 길이를 계산한다.
|
|
unsigned int nTemp = 0;
|
|
|
|
nTemp = 4 + szFileName.size(); // File Name ( 4 + 가변 )
|
|
|
|
stHeader.data_length = htonl( nTemp );
|
|
|
|
// Packet Header 정보 전송
|
|
if( WriteN( &stHeader, m_nPacketHeaderLen ) != m_nPacketHeaderLen )
|
|
{
|
|
LOG( LERR, "TOTO File[%s] Check request send failed.", szFileName.c_str() );
|
|
return false;
|
|
}
|
|
|
|
// Packet Data 부분 전송
|
|
|
|
// 1. File Name 부분
|
|
nTemp = htonl( szFileName.size() );
|
|
WriteN( &nTemp, 4 );
|
|
WriteN( szFileName.c_str(), szFileName.size() );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// NEW 2016-05-04 huibong 토토디스크 지원용 기능 추가 (#27460, #27533)
|
|
/// @brief File Check 요청에 대한 처리 결과를 ftsd 로 부터 수신한다.
|
|
int CFtsdSocketControl::GetFileCheckTOTOResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage
|
|
, unsigned long long& nFileSize, std::string& szTotoMd5, std::string& szChecksum, std::string& szDnaCheckKey )
|
|
{
|
|
|
|
if( IsValidSocket() == false )
|
|
return -1;
|
|
|
|
int nRead;
|
|
bool isAlivePacket;
|
|
do
|
|
{
|
|
isAlivePacket = false;
|
|
|
|
// Socket 으로 부터 Packet Header 부분 수신.
|
|
// 수신된 정보는 멤버변수에 저장처리.
|
|
nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, nTimeout );
|
|
|
|
// nRead 0: Socket Closed, -1: error , -2: Timeout 이므로
|
|
if( nRead == -2 )
|
|
return 0; // Timeout 반환.
|
|
else if( nRead == 0 || nRead == -1 )
|
|
return -1; // Socket Close 또는 오류 발생시
|
|
|
|
// STX code 검사.
|
|
if( m_packetHeader.stx != HEADER_STX_CODE )
|
|
{
|
|
LOG( LERR, "Not valid stx code." );
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Data Length 부분 값을 멤버 변수에 저장처리.
|
|
m_nPacketDataLen = ntohl( m_packetHeader.data_length );
|
|
|
|
// Alive Check Packet 인 경우 해당 패킷은 무시처리 후 다시 수신 처리한다.
|
|
if( m_packetHeader.type == HEADER_TYPE_REQUEST
|
|
&& m_packetHeader.command[0] == COMMON_ALIVE_CHECK
|
|
&& m_nPacketDataLen == 0 )
|
|
{
|
|
isAlivePacket = true;
|
|
}
|
|
|
|
} while( isAlivePacket == true );
|
|
|
|
// Alive Packet 이 아닌 경우 해당 Packet 에 대한 Check에 대한 응답 패킷인지 검사.
|
|
if( m_packetHeader.type != HEADER_TYPE_RESPONSE
|
|
|| m_packetHeader.command[0] != CONTROL_FILE_CHECK_TOTO )
|
|
{
|
|
// 다른 패킷이 들어온 경우
|
|
|
|
// ** 정석대로라면 그냥 냅둬어 수신부에서 처리해야 하지만
|
|
// 현재 수신 처리부가 없어 당장 문제가 생길수 있으므로
|
|
// 데이터 부분까지 수신하여 임시버퍼에 저장처리 해 놓는다.
|
|
GetPacketData( m_nPacketDataLen );
|
|
return 2;
|
|
}
|
|
|
|
// Check 에 대한 응답 패킷이 경우.
|
|
|
|
// 1. 성공, 실패 여부 판단.
|
|
if( m_packetHeader.result[0] != HEADER_RESULT_SUCCESS )
|
|
{
|
|
// 오류가 발생한 경우임
|
|
bSuccess = false;
|
|
|
|
// Packet Data 상에서 오류 메시지를 수신받아 반환 처리.
|
|
if( GetPacketData( m_nPacketDataLen, szErrorMessage ) == false )
|
|
{
|
|
LOG( LERR, "Error msg receive failed." );
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
// 2. 성공인 경우
|
|
bSuccess = true;
|
|
|
|
// 2.1 File Size 정보 추출..
|
|
if( GetPacketData( 8 ) == false )
|
|
{
|
|
LOG( LERR, "File size receive fail." );
|
|
return -1;
|
|
}
|
|
nFileSize = GetDataToUInt64( m_tempBuffer );
|
|
|
|
|
|
unsigned int nLength = 0;
|
|
|
|
|
|
// 2.2 totorasa 용 MD5 Hash 값 정보 수신 및 저장
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "szTotoMd5 length receive fail." );
|
|
return -1;
|
|
}
|
|
|
|
nLength = GetDataToUInt( m_tempBuffer, true );
|
|
if( nLength > 0 )
|
|
{
|
|
// 추출된 정보 저장.
|
|
GetPacketData( nLength, szTotoMd5 );
|
|
}
|
|
|
|
// 2.3 totorasa 용 Checksum 값 정보 수신 및 저장
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "szChecksum length receive fail." );
|
|
return -1;
|
|
}
|
|
|
|
nLength = GetDataToUInt( m_tempBuffer, true );
|
|
if( nLength > 0 )
|
|
{
|
|
// 추출된 정보 저장.
|
|
GetPacketData( nLength, szChecksum );
|
|
}
|
|
|
|
// 2.4 totorasa 용 DNA CHECK Key 값 정보 수신 및 저장
|
|
if( GetPacketData( 4 ) == false )
|
|
{
|
|
LOG( LERR, "szDnaCheckKey length receive fail." );
|
|
return -1;
|
|
}
|
|
|
|
nLength = GetDataToUInt( m_tempBuffer, true );
|
|
if( nLength > 0 )
|
|
{
|
|
// 추출된 정보 저장.
|
|
GetPacketData( nLength, szDnaCheckKey );
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// @brief Packet Header 부분의 수신 처리를 위한 함수.
|
|
/// @param timeout [in] 대기시간.
|
|
/// @retrun 성공시 true, 오류 발생및 실패시 fasle 반환.
|
|
bool CFtsdSocketControl::GetPacketHeader( int timeout )
|
|
{
|
|
if( IsValidSocket() == false )
|
|
return false;
|
|
|
|
int nRead;
|
|
bool isAlivePacket;
|
|
do
|
|
{
|
|
isAlivePacket = false;
|
|
|
|
// Socket 으로 부터 Packet Header 부분 수신.
|
|
// 수신된 정보는 멤버변수에 저장처리.
|
|
nRead = ReadNTimeout( &m_packetHeader, m_nPacketHeaderLen, timeout );
|
|
|
|
// 오류 발생시
|
|
if( nRead <= 0 )
|
|
return false;
|
|
|
|
// STX code 검사.
|
|
if( m_packetHeader.stx != HEADER_STX_CODE )
|
|
{
|
|
LOG( LERR, "Not valid stx code.");
|
|
return false;
|
|
}
|
|
|
|
// Data Length 부분 값을 멤버 변수에 저장처리.
|
|
m_nPacketDataLen = ntohl( m_packetHeader.data_length );
|
|
|
|
// Alive Check Packet 인 경우 해당 패킷은 무시처리 후 다시 수신 처리한다.
|
|
if( m_packetHeader.type == HEADER_TYPE_REQUEST
|
|
&& m_packetHeader.command[0] == COMMON_ALIVE_CHECK
|
|
&& m_nPacketDataLen == 0 )
|
|
{
|
|
isAlivePacket = true;
|
|
}
|
|
|
|
} while( isAlivePacket == true );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/// @brief socket 에서 지정된 크기만큼의 데이터를 읽어 출력변수에 저장처리.
|
|
/// @param size [in] read 할 데이터 크기
|
|
/// @param value [out] 읽은 데이터를 저장할 string 변수
|
|
/// @return On success return true, otherwise return false.
|
|
bool CFtsdSocketControl::GetPacketData( unsigned int& size, std::string& value )
|
|
{
|
|
// 1. 수신할 크기가 임시버퍼보다 큰 경우 새로운 버퍼를 생성한다.
|
|
BYTE * pBuffer = NULL;
|
|
bool bNewBufferCreated = false;
|
|
if( size > DEFAULT_SOCKET_TEMP_BUFFER_SIZE )
|
|
{
|
|
pBuffer = new BYTE[size]; // 신규 메모리 할당.
|
|
bNewBufferCreated = true;
|
|
}
|
|
else
|
|
pBuffer = m_tempBuffer;
|
|
|
|
// 2. 데이터 수신 처리.
|
|
int nRead = ReadNTimeout( pBuffer, size, FTSD_DATA_RECV_TIMEOUT );
|
|
|
|
// 오류 발생시
|
|
if( nRead <= 0 )
|
|
{
|
|
// 신규로 생성된 버퍼인 경우 메모리 해제 처리.
|
|
if( bNewBufferCreated == true )
|
|
delete [] pBuffer;
|
|
|
|
return false;
|
|
}
|
|
|
|
// 3. 수신 데이터 저장 처리 - 기존 데이터 뒤에 붙여 준다=> 이게 사용하기 편함.
|
|
value.append( (char *)pBuffer, size );
|
|
|
|
// 신규로 생성된 버퍼인 경우 메모리 해제 처리.
|
|
if( bNewBufferCreated == true )
|
|
delete [] pBuffer;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// @brief socket 에서 지정된 크기만큼의 데이터를 읽어 내부 임시버퍼인 m_tempBuffer 에 저장처리.
|
|
/// @param size [in] read 할 데이터 크기
|
|
/// @return On success return true, otherwise return false.
|
|
bool CFtsdSocketControl::GetPacketData( unsigned int size )
|
|
{
|
|
// 1. 수신할 크기가 임시버퍼보다 큰 경우 오류 반환.
|
|
if( size > DEFAULT_SOCKET_TEMP_BUFFER_SIZE )
|
|
return false;
|
|
|
|
// 2. 데이터 수신 처리.
|
|
int nRead = ReadNTimeout( m_tempBuffer, size, FTSD_DATA_RECV_TIMEOUT );
|
|
|
|
// 오류 발생시
|
|
if( nRead <= 0 )
|
|
return false;
|
|
|
|
// 3. 정상인 경우는 ReadNTimeout 함수가 무조건 요청 크기만큼 read 처리하므로 정상수신임.
|
|
return true;
|
|
}
|
|
|
|
/// @brief 전달받은 데이터를 unsigned int 형으로 변환처리 및 Endian 변환
|
|
unsigned int CFtsdSocketControl::GetDataToUInt( BYTE * pValue, bool bConvertEndian )
|
|
{
|
|
BYTE tempBuffer[4];
|
|
unsigned int result;
|
|
|
|
memcpy(tempBuffer, pValue, 4);
|
|
unsigned int * pInt = (unsigned int *)tempBuffer;
|
|
|
|
// Endian 변환처리.
|
|
if( bConvertEndian == true )
|
|
{
|
|
result = ntohl( *pInt );
|
|
}
|
|
else
|
|
result = *pInt;
|
|
|
|
return result;
|
|
}
|
|
|
|
unsigned long long CFtsdSocketControl::GetDataToUInt64( BYTE * pValue )
|
|
{
|
|
unsigned long long * pResult;
|
|
BYTE tempBuffer[8];
|
|
memcpy(tempBuffer, pValue, 8);
|
|
|
|
pResult = (unsigned long long *)tempBuffer;
|
|
|
|
return *pResult;
|
|
}
|
|
|