📄 datasocket.cpp
字号:
/********************************************************************/
/* */
/* DataSocket.cpp */
/* */
/* Implementation of the Data Socket. */
/* */
/* Programmed by Pablo van der Meer */
/* http://www.pablovandermeer.nl */
/* */
/* Last updated: 10 july 2002 */
/* */
/********************************************************************/
#include "stdafx.h"
#include "resource.h"
#include "DataSocket.h"
#include "ConnectSocket.h"
#include "ConnectThread.h"
#include <afxpriv.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PACKET_SIZE 4096
/********************************************************************/
/* */
/* Function name : CDataSocket::CDataSocket */
/* Description : Constructor */
/* */
/********************************************************************/
CDataSocket::CDataSocket(CConnectSocket *pSocket, int nTransferType)
{
m_nTransferType = nTransferType;
m_pConnectSocket = pSocket;
m_nStatus = XFERMODE_IDLE;
m_strData = "";
m_File.m_hFile = NULL;
m_bConnected = FALSE;
m_bPassiveMode = FALSE;
}
/********************************************************************/
/* */
/* Function name : CDataSocket::~CDataSocket */
/* Description : Destructor */
/* */
/********************************************************************/
CDataSocket::~CDataSocket()
{
m_bConnected = FALSE;
TRACE0("CDataSocket destroyed.\n");
}
#if 0
BEGIN_MESSAGE_MAP(CDataSocket, CAsyncSocket)
//{{AFX_MSG_MAP(CDataSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/********************************************************************/
/* */
/* Function name : CDataSocket::OnSend */
/* Description : Called by the framework to notify socket that */
/* it can send data by calling the Send method. */
/* */
/********************************************************************/
void CDataSocket::OnSend(int nErrorCode)
{
switch(m_nStatus)
{
case XFERMODE_LIST:
{
while (m_nTotalBytesTransfered < m_nTotalBytesSend)
{
DWORD dwRead;
int dwBytes;
CString strData;
dwRead = m_strData.GetLength();
if (dwRead <= PACKET_SIZE)
{
strData = m_strData;
}
else
{
strData = m_strData.Left(PACKET_SIZE);
dwRead = strData.GetLength();
}
if ((dwBytes = Send(strData, dwRead)) == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
Sleep(0);
break;
}
else
{
TCHAR szError[256];
wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
// close the data connection.
Close();
m_nTotalBytesSend = 0;
m_nTotalBytesTransfered = 0;
// change status
m_nStatus = XFERMODE_IDLE;
m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
}
}
else
{
m_nTotalBytesTransfered += dwBytes;
m_strData = m_strData.Mid(dwBytes);
((CConnectThread *)AfxGetThread())->IncSentBytes(dwBytes);
}
}
if (m_nTotalBytesTransfered == m_nTotalBytesSend)
{
// close the data connection.
Close();
m_nTotalBytesSend = 0;
m_nTotalBytesTransfered = 0;
// change status
m_nStatus = XFERMODE_IDLE;
// tell the client the transfer is complete.
m_pConnectSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
}
break;
// if (m_bPassiveMode)
/* int dwBytes;
if (dwBytes = Send(m_strData, m_strData.GetLength()) == SOCKET_ERROR)
{
m_nStatus = XFERMODE_IDLE;
}
m_nStatus = XFERMODE_IDLE;
Close();
// tell the client the transfer is complete.
m_pConnectSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
break; */
}
case XFERMODE_SEND:
{
while (m_nTotalBytesTransfered < m_nTotalBytesSend)
{
// allocate space to store data
byte data[PACKET_SIZE];
m_File.Seek(m_nTotalBytesTransfered, CFile::begin);
DWORD dwRead = m_File.Read(data, PACKET_SIZE);
int dwBytes;
if ((dwBytes = Send(data, dwRead)) == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
Sleep(0);
break;
}
else
{
TCHAR szError[256];
wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
// close file.
m_File.Close();
m_File.m_hFile = NULL;
// close the data connection.
Close();
m_nTotalBytesSend = 0;
m_nTotalBytesTransfered = 0;
// change status
m_nStatus = XFERMODE_IDLE;
m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// download failed
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_DOWNLOADFAILED);
}
}
else
{
m_nTotalBytesTransfered += dwBytes;
((CConnectThread *)AfxGetThread())->IncSentBytes(dwBytes);
}
}
if (m_nTotalBytesTransfered == m_nTotalBytesSend)
{
// close file.
m_File.Close();
m_File.m_hFile = NULL;
// close the data connection.
Close();
m_nTotalBytesSend = 0;
m_nTotalBytesTransfered = 0;
// change status
m_nStatus = XFERMODE_IDLE;
// tell the client the transfer is complete.
m_pConnectSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
// download successfull
((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_DOWNLOADSUCCEEDED);
}
break;
}
default:
break;
}
CAsyncSocket::OnSend(nErrorCode);
}
/********************************************************************/
/* */
/* Function name : CDataSocket::OnConnect */
/* Description : Called by the framework to notify connecting */
/* socket that its connection attempt is completed */
/* */
/********************************************************************/
void CDataSocket::OnConnect(int nErrorCode)
{
if (nErrorCode)
{
m_nStatus = XFERMODE_ERROR;
m_pConnectSocket->SendResponse("425 Can't open data connection.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
}
else
{
switch (m_nTransferType)
{
case 0: // List Directory
m_nStatus = XFERMODE_LIST;
m_bConnected = TRUE;
// m_nTotalBytesSend = m_strData.GetLength();
// m_nTotalBytesTransfered = 0;
OnSend(0);
// Send(m_strData, m_strData.GetLength());
break;
case 1: // Send File
if (PrepareSendFile(m_strData))
{
m_nStatus = XFERMODE_SEND;
m_bConnected = TRUE;
}
else
{
Close();
}
break;
case 2: // Receive File
if (PrepareReceiveFile(m_strData))
{
m_nStatus = XFERMODE_RECEIVE;
m_bConnected = TRUE;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -