?? datasocket.cpp
字號:
{
// shutdown sends
ShutDown(1);
if (m_nStatus == XFERMODE_RECEIVE)
{
while(Receive() != 0)
{
// receive remaining data
}
}
else
{
m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// upload failed
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
}
}
m_nStatus = XFERMODE_IDLE;
m_bConnected = FALSE;
CAsyncSocket::OnClose(nErrorCode);
}
/********************************************************************/
/* */
/* Function name : CDataSocket::OnAccept */
/* Description : Notify this listening socket that it can accept */
/* pending connection requests. */
/* */
/********************************************************************/
void CDataSocket::OnAccept(int nErrorCode)
{
// Accept the connection using a temp CSocket object.
CAsyncSocket tmpSocket;
Accept(tmpSocket);
SOCKET socket = tmpSocket.Detach();
Close();
Attach(socket);
m_bConnected = TRUE;
if (!m_bInitialized)
SetTransferType(m_nTransferType);
CAsyncSocket::OnAccept(nErrorCode);
}
/********************************************************************/
/* */
/* Function name : CDataSocket::GetStatus */
/* Description : Get socket status. */
/* */
/********************************************************************/
int CDataSocket::GetStatus()
{
return m_nStatus;
}
/********************************************************************/
/* */
/* Function name : CDataSocket::PrepareSendFile */
/* Description : Prepare socket to send a file. */
/* */
/********************************************************************/
BOOL CDataSocket::PrepareSendFile(LPCTSTR lpszFilename)
{
// close file if it's already open
if (m_File.m_hFile != NULL)
{
m_File.Close();
}
// open source file
if (!m_File.Open(lpszFilename, CFile::modeRead | CFile::typeBinary))
{
return FALSE;
}
m_nTotalBytesSend = m_File.GetLength();
if (m_dwRestartOffset < m_nTotalBytesSend)
m_nTotalBytesTransfered = m_dwRestartOffset;
else
m_nTotalBytesTransfered = 0;
return TRUE;
}
/********************************************************************/
/* */
/* Function name : CDataSocket::PrepareReceiveFile */
/* Description : Prepare socket to receive a file. */
/* */
/********************************************************************/
BOOL CDataSocket::PrepareReceiveFile(LPCTSTR lpszFilename)
{
// close file if it's already open
if (m_File.m_hFile != NULL)
{
m_File.Close();
}
// open destination file
if (!m_File.Open(lpszFilename, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate | CFile::shareDenyWrite))
{
return FALSE;
}
m_nTotalBytesReceive = 0;
m_nTotalBytesTransfered = 0;
if (m_dwRestartOffset)
{
m_File.SetLength(m_dwRestartOffset);
m_File.SeekToEnd();
}
return TRUE;
}
/********************************************************************/
/* */
/* Function name : CDataSocket::OnReceive */
/* Description : Called by the framework to notify this socket */
/* that there is data in the buffer that can be */
/* retrieved by calling the Receive member function.*/
/* */
/********************************************************************/
void CDataSocket::OnReceive(int nErrorCode)
{
CAsyncSocket::OnReceive(nErrorCode);
Receive();
}
/********************************************************************/
/* */
/* Function name : CDataSocket::Receive */
/* Description : Receive data from a socket */
/* */
/********************************************************************/
int CDataSocket::Receive()
{
int nRead = 0;
if (m_nStatus == XFERMODE_RECEIVE)
{
if (m_File.m_hFile == NULL)
return 0;
byte data[PACKET_SIZE];
nRead = CAsyncSocket::Receive(data, PACKET_SIZE);
switch(nRead)
{
case 0:
{
m_File.Close();
m_File.m_hFile = NULL;
Close();
// tell the client the transfer is complete.
m_pConnectSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// upload succesfull
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADSUCCEEDED);
break;
}
case SOCKET_ERROR:
{
if (GetLastError() != WSAEWOULDBLOCK)
{
m_File.Close();
m_File.m_hFile = NULL;
Close();
m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// upload failed
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
}
break;
}
default:
{
((CConnectThread *)AfxGetThread())->IncReceivedBytes(nRead);
TRY
{
m_File.Write(data, nRead);
}
CATCH_ALL(e)
{
m_File.Close();
m_File.m_hFile = NULL;
Close();
m_pConnectSocket->SendResponse("450 Can't access file.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// upload failed
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
return 0;
}
END_CATCH_ALL;
break;
}
}
}
return nRead;
}
/********************************************************************/
/* */
/* Function name : CDataSocket::SetData */
/* Description : Set data that is initially send to client. */
/* */
/********************************************************************/
void CDataSocket::SetData(LPCTSTR lpszData)
{
m_strData = lpszData;
m_nTotalBytesSend = m_strData.GetLength();
m_nTotalBytesTransfered = 0;
}
/********************************************************************/
/* */
/* Function name : CDataSocket::SetTransferType */
/* Description : Set transfer type: */
/* 0 = LIST DIR, 1 = SEND FILE, 2 = RECEIVE FILE */
/* */
/********************************************************************/
void CDataSocket::SetTransferType(int nType, BOOL bWaitForAccept)
{
m_nTransferType = nType;
if (bWaitForAccept && !m_bConnected)
{
m_bInitialized = FALSE;
return;
}
if (m_bConnected && m_nTransferType != -1)
m_pConnectSocket->SendResponse("150 Connection accepted");
m_bInitialized = TRUE;
switch(m_nTransferType)
{
case 0: // List Directory
m_nStatus = XFERMODE_LIST;
OnSend(0);
break;
case 1: // Send File
if (PrepareSendFile(m_strData))
{
m_nStatus = XFERMODE_SEND;
m_bConnected = TRUE;
OnSend(0);
}
else
{
Close();
}
break;
case 2: // Receive File
if (PrepareReceiveFile(m_strData))
{
m_nStatus = XFERMODE_RECEIVE;
m_bConnected = TRUE;
OnSend(0);
}
else
{
Close();
m_pConnectSocket->SendResponse("450 Can't access file.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// upload failed
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
}
break;
default:
m_bInitialized = FALSE;
break;
}
}
/********************************************************************/
/* */
/* Function name : CDataSocket::SetRestartOffset */
/* Description : Set offset of where to restart file transfer. */
/* */
/********************************************************************/
void CDataSocket::SetRestartOffset(DWORD dwOffset)
{
m_dwRestartOffset = dwOffset;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -