⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datasocket.cpp

📁 这时一个ftp服务器,可以根据这个小的服务器原型做出更大的服务器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************/
/*																	*/
/*  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 + -