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

📄 view_old.cpp

📁 简单的ftp客户端下载程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// View.cpp : implementation of the CMiniFTPView class
//

#include "stdafx.h"
#include "miniftp.h"

#include "Doc.h"
#include "View.h"
//#include "cwinsock.h"    // in this files .h
#include "mainfrm.h"
#include "conndlg.h"
#include "XportDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WM_WINSOCK_EVENT_FRAME_CONTROL (WM_USER+4)	 // for winsock messages
#define WM_WINSOCK_EVENT_VU_CONTROL (WM_USER+4+10)	 // for winsock messages
#define WM_WINSOCK_EVENT_FRAME_LISTEN (WM_USER+6)	 // for winsock messages
#define WM_WINSOCK_EVENT_VU_LISTEN (WM_USER+6+10)	 // for winsock messages
#define WM_WINSOCK_EVENT_FRAME_DATA (WM_USER+8)	 // for winsock messages
#define WM_WINSOCK_EVENT_VU_DATA (WM_USER+8+10)	 // for winsock messages

/////////////////////////////////////////////////////////////////////////////
// CMiniFTPView

IMPLEMENT_DYNCREATE(CMiniFTPView, CEditView)

BEGIN_MESSAGE_MAP(CMiniFTPView, CEditView)
	//{{AFX_MSG_MAP(CMiniFTPView)
	ON_COMMAND(ID_CONNECT, OnConnect)
	ON_COMMAND(ID_CLOSECONN, OnCloseconn)
	ON_COMMAND(ID_CLEARVIEW, OnClearview)
	ON_UPDATE_COMMAND_UI(ID_CLOSECONN, OnUpdateCloseconn)
	ON_UPDATE_COMMAND_UI(ID_CONNECT, OnUpdateConnect)
	ON_WM_TIMER()
	ON_COMMAND(ID_FSETTINGS, OnFsettings)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_WINSOCK_EVENT_VU_CONTROL,OnWinsockEventControl)
	ON_MESSAGE(WM_WINSOCK_EVENT_VU_LISTEN,OnWinsockEventListen)
	ON_MESSAGE(WM_WINSOCK_EVENT_VU_DATA,OnWinsockEventData)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMiniFTPView construction/destruction
CMiniFTPView::CMiniFTPView()
{
	WSAData WsaData;
	int ret = WSAStartup(0x0101, &WsaData);
	if( ret != 0 )
	{
		AfxMessageBox("WSAStartup failed");
	}

	m_sktControl = INVALID_SOCKET;
	m_sktListen = INVALID_SOCKET;
	m_sktData = INVALID_SOCKET;


	//m_pWinsockControl = NULL;
	//m_pWinsockListen = NULL;
	//m_pWinsockData = NULL;
	m_nState = 0;
	m_pXferFilePointer = NULL;
	m_bTimerOn = FALSE;
	m_bWaitingForTimeout = FALSE;
	MakeSafeState();
	m_nRadioASCII = AfxGetApp()->GetProfileInt("Setting", "ASCII", 0);
	m_sExportFileName = AfxGetApp()->GetProfileString("Setting", "Name", "RETRFILE.txt");
}

void CMiniFTPView::MakeSafeState(void)
{
	if( m_bWaitingForTimeout )
	{
		KillTimer( ID_MYTIMEOUT );
	}
	m_bWaitingForTimeout = FALSE;
	if( m_bTimerOn )
	{
		KillTimer( ID_MYTIMER );
	}
	m_bTimerOn = FALSE; 

	m_nState = 0;

	if( m_pXferFilePointer != NULL)
	{
		fclose( m_pXferFilePointer );
		m_pXferFilePointer = NULL;
	}
	//m_bInTransit = FALSE;
	//m_bStartLogon = FALSE;
	//m_bStartCommand = FALSE;
	m_bReplyReceived = FALSE;
	//m_bCommandToSend = FALSE;
	m_bTimerOn = FALSE;
	m_bBusy = FALSE;
	m_bWaitingForTimeout = FALSE;
	strcpy(m_szCommandToServer, "" );
	m_bSavingFile = FALSE;
	m_bFileHasBeenSaved = FALSE;
	m_bStoringFile = FALSE;
	m_bFileHasBeenStored = FALSE;

}

CMiniFTPView::~CMiniFTPView()
{
	if( m_sktData != INVALID_SOCKET )
	{
		closesocket(m_sktData);
	}
	if( m_sktListen != INVALID_SOCKET )
	{
		closesocket(m_sktListen);
	}	
	if( m_sktControl != INVALID_SOCKET )
	{
		closesocket(m_sktControl);
	}	
	WSACleanup();
}

BOOL CMiniFTPView::PreCreateWindow(CREATESTRUCT& cs)
{
	BOOL bPreCreated = CEditView::PreCreateWindow(cs);

	cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL);	// Enable word-wrapping

	cs.style |=	ES_READONLY; // make read only - it is a log window
	return bPreCreated;
}

/////////////////////////////////////////////////////////////////////////////
// CMiniFTPView drawing

void CMiniFTPView::OnDraw(CDC* pDC)
{
	CMiniFTPDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
}

/////////////////////////////////////////////////////////////////////////////
// CMiniFTPView diagnostics

#ifdef _DEBUG
void CMiniFTPView::AssertValid() const
{
	CEditView::AssertValid();
}

void CMiniFTPView::Dump(CDumpContext& dc) const
{
	CEditView::Dump(dc);
}

CMiniFTPDoc* CMiniFTPView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMiniFTPDoc)));
	return (CMiniFTPDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMiniFTPView message handlers

/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::Log(const char * szBuffer)
{
	int nChars=GetWindowTextLength();    // get the index of the last line

 	// point end of document
	GetEditCtrl().SetSel( nChars,nChars );
	GetEditCtrl().ReplaceSel((LPCSTR)szBuffer);     // display text

	// defeat the final "save document" dialog on app exit
	GetDocument()->SetModifiedFlag(FALSE); 
}

/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnTimer(UINT nIDEvent) 
{
	if( nIDEvent == ID_MYTIMER)
	{
		StateMachine();
	}
	else if( nIDEvent == ID_MYTIMEOUT)
	{
		MakeSafeState();
		Log("\r\nMiniFTP Status>Client Timeout\r\n\r\n");
	}
}

////////////////////////////////////////////////////////////////////////////
// the major sequencer for client/server stuff
void CMiniFTPView::StateMachine(void) 
{
	CString sOut;

	switch ( m_nState ) 	  // which state are we in now ?
	{
		case 0:
			if( !m_sCommandList.IsEmpty() && !m_bBusy )
			{
				m_bBusy = TRUE;
				SetTimer(ID_MYTIMEOUT, 30000, NULL);
				m_bWaitingForTimeout = TRUE;
				m_bReplyReceived = FALSE;
				sOut = m_sCommandList.GetHead();
				m_sCommandList.RemoveHead();
				DoCommand( sOut );
				m_nState = 1;
			}
			break;
		case 1:
			if( m_bReplyReceived )
			{
				m_bReplyReceived = FALSE;
				m_nState = 0;
				KillTimer(ID_MYTIMEOUT);
				m_bWaitingForTimeout = FALSE;
				if( m_sCommandList.IsEmpty() )
				{
					KillTimer(ID_MYTIMER);
					m_bTimerOn =FALSE;
				}
				m_bBusy = FALSE;
			}
			break;
	}
}


/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::DisplaySktRead( char * szBuffer )
{
	char * str=strtok(szBuffer,"\n");
	while( str && *str)
	{
		Log((const char *)str);
		int nLen = strlen(str);
		int nCount = (int)(str-szBuffer)+nLen;
		if( nCount != NUM1024 )
		{
		   Log("\r\n");
		}
		else
		{
			ASSERT( nCount == NUM1024 );
			char c = *(szBuffer + NUM1024 -1);
			if( c == '\n' )
			{
				Log("\r\n");
			}
		}
		str=strtok((char *)NULL,"\n");
	}
}

/////////////////////////////////////////////////////////////////////////////
LONG CMiniFTPView::OnWinsockEventControl (WPARAM wParam, LPARAM lParam)
{
	ASSERT( m_sktControl == wParam );
	memset( m_szControlReplyBuffer, 0, NUM1024+2);
	// this memset trick avoids having strtok insert a wild \0 somewhere bad
	//		it is guaranteed to find a \n (the delimiter in this case) before
	//		running off into other memory
	memset( m_szControlReplyBuffer+NUM1024, '\n', 1); 
	CString sOut;

	switch ( WSAGETSELECTEVENT(lParam) ) 	  // which message arrived?
	{
		case FD_CLOSE:
			sOut.Format( "\r\nMiniFTP Status>Control Connection closed by server (socket %d)\r\n\r\n", wParam);
			Log(sOut);
			m_sktControl = INVALID_SOCKET;
			break;

		case FD_READ:
			recv( m_sktControl, m_szControlReplyBuffer, NUM1024, 0 );
			DisplaySktRead( m_szControlReplyBuffer );
			m_bReplyReceived = TRUE;
			break;

		case FD_ACCEPT:
			/*ASSERT(m_pWinsockListen != NULL);
			sTemp = m_pWinsockListen->Accept(NULL,NULL);*/
			//sTemp = m_pWinsockListen->GetWSocket();
			/*ASSERT(sTemp != INVALID_SOCKET);
			m_pWinsockData->SetSocket(sTemp);
			m_pWinsockData->SetSockOpt(SOL_SOCKET,SO_LINGER,0,0);	
			m_pWinsockData->SetSockOpt(SOL_SOCKET,SO_REUSEADDR,0,0);
			m_pWinsockData->SetSockOpt(SOL_SOCKET,SO_KEEPALIVE,0,0);
			m_pWinsockData->SetSockOpt(SOL_SOCKET,SO_OOBINLINE,0,0);*/
			//m_pWinsockListen->CloseSocket();
			// its a window so destroy it first
			//m_pWinsockListen->DestroyWindow();
			//delete m_pWinsockListen;
			//m_pWinsockListen = NULL; 

			//sOut.Format("\r\nMiniFTP Status>Data Connection made OK (socket %d)\r\n\r\n", sTemp);
			sOut.Format("\r\nMiniFTP Status>Data Connection made OK\r\n\r\n");
			Log(sOut);
			break;

		case FD_WRITE:
				recv( m_sktControl, m_szControlReplyBuffer, NUM1024, 0 );
				DisplaySktRead( m_szControlReplyBuffer );
			break;
	}
	return 0L;
}

/*  FOR REFERENCE
#define FD_READ         0x01
#define FD_WRITE        0x02
#define FD_OOB          0x04
#define FD_ACCEPT       0x08
#define FD_CONNECT      0x10
#define FD_CLOSE        0x20 */


/////////////////////////////////////////////////////////////////////////////
LONG CMiniFTPView::OnWinsockEventListen (WPARAM wParam, LPARAM lParam)
{
	//ASSERT( m_sktListen == wParam );
	if( m_sktListen != wParam )
	{
		int asdf = 1;
	}
	memset( m_szControlReplyBuffer, 0, NUM1024+2);
	// this memset trick avoids having strtok insert a wild \0 somewhere bad
	//		it is guaranteed to find a \n (the delimiter in this case) before
	//		running off into other memory
	memset( m_szControlReplyBuffer+NUM1024, '\n', 1); 
	CString sOut;

	switch ( WSAGETSELECTEVENT(lParam) ) 	  // which message arrived?
	{
		case FD_CLOSE:
			sOut.Format( "\r\nMiniFTP Status>Listen Connection closed by server (socket %d)\r\n\r\n", wParam);
			Log(sOut);
			m_sktListen = INVALID_SOCKET;
			break;

		case FD_READ:
			recv( m_sktListen, m_szControlReplyBuffer, NUM1024, 0 );
			DisplaySktRead( m_szControlReplyBuffer );
			m_bReplyReceived = TRUE;
			break;

		case FD_ACCEPT:
			//ASSERT(m_pWinsockListen != NULL);
			m_sktData = accept( m_sktListen, NULL, NULL);
			//sTemp = m_pWinsockListen->GetWSocket();
			//ASSERT(sTemp != INVALID_SOCKET);
			//m_pWinsockData->SetSocket(sTemp);
			setsockopt( m_sktData, SOL_SOCKET, SO_LINGER, 0, 0);	
			setsockopt( m_sktData, SOL_SOCKET, SO_REUSEADDR, 0, 0);
			setsockopt( m_sktData, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
			WSAAsyncSelect ( m_sktData, AfxGetMainWnd()->m_hWnd, 
					WM_WINSOCK_EVENT_FRAME_DATA, 
					FD_WRITE|FD_READ|FD_CLOSE|FD_ACCEPT);

			//m_pWinsockData->SetSockOpt(SOL_SOCKET,SO_OOBINLINE,0,0);*/
			//m_pWinsockListen->CloseSocket();
			// its a window so destroy it first
			//m_pWinsockListen->DestroyWindow();
			//delete m_pWinsockListen;
			//m_pWinsockListen = NULL; 

			sOut.Format("\r\nMiniFTP Status>Data Connection made OK (socket %d)\r\n\r\n", m_sktData);
			//sOut.Format("\r\nMiniFTP Status>Data Connection made OK\r\n\r\n");
			Log(sOut);
			break;

		case FD_WRITE:
				recv( m_sktListen, m_szControlReplyBuffer, NUM1024, 0 );
				DisplaySktRead( m_szControlReplyBuffer );
			break;
	}
	return 0L;
}

/////////////////////////////////////////////////////////////////////////////
LONG CMiniFTPView::OnWinsockEventData (WPARAM wParam, LPARAM lParam)
{
	ASSERT( m_sktData == wParam );
	memset( m_szDataInBuffer, 0, NUM1024+2);
	// this memset trick avoids having strtok insert a wild \0 somewhere bad
	//		it is guaranteed to find a \n (the delimiter in this case) before
	//		running off into other memory
	memset( m_szDataInBuffer+NUM1024, '\n', 1); 

	CString sOut;
	int nLen, nRet;
	BOOL bCancel = FALSE;
	char  *str;
	int nClose;
	UINT nr;

	switch ( WSAGETSELECTEVENT(lParam) ) 	  // which message arrived?
	{
		case FD_CLOSE:
			sOut.Format( "\r\nMiniFTP Status>Data Connection closed by server (socket %d)\r\n\r\n", wParam);
			Log(sOut);
			nClose = closesocket(m_sktData);
			m_sktData = INVALID_SOCKET;
			// close the listener too
			if( m_sktListen != INVALID_SOCKET )
			{
				nClose = closesocket(m_sktListen);
			}
			m_sktListen = INVALID_SOCKET;
			break;

		case FD_READ: //asdf
			// just a plain data socket (no file saving)  - get the data to the screen
			if( !m_bSavingFile) 
			{
				recv( m_sktData, m_szDataInBuffer, NUM1024, 0 );
				DisplaySktRead( m_szDataInBuffer );
			}
			else // we are saving file
			{
				if( m_bWaitingForTimeout ) // may be a big file
				{
					KillTimer(ID_MYTIMEOUT);
					m_bWaitingForTimeout = FALSE;
				}

				ASSERT( m_pXferFilePointer==NULL );
				m_pXferFilePointer = fopen( (const char *)m_sExportFileName, "r" );
				if( m_pXferFilePointer )
				{
					fclose( m_pXferFilePointer );
					sOut.Format( "File %s\nalready exists.\n\nOverwrite?", m_sExportFileName);
					if( AfxMessageBox( sOut, MB_YESNO ) != IDYES )
					{
						bCancel = TRUE;
					}
				}
				if( bCancel )
				{
					BeginWaitCursor(); // show hourglass 
					// just burn it off
					do
					{
						nRet = recv( m_sktData, m_szDataInBuffer, NUM1024, 0 );
					} while( nRet != SOCKET_ERROR && nRet > 0 ); 
					m_bFileHasBeenSaved = TRUE; // kinda misnomer - more like "operation complete"
					m_bSavingFile = FALSE;
					m_pXferFilePointer = NULL;
					EndWaitCursor(); // kill hourglass 
				}
				else if( !bCancel && !m_nRadioASCII )
				{
					// a binary store to disk
					BeginWaitCursor(); // show hourglass 
					m_pXferFilePointer = fopen( (const char *)m_sExportFileName, "wb" );
					ASSERT( m_pXferFilePointer );
					do
					{
						nRet = recv( m_sktData, m_szDataInBuffer, NUM1024, 0 );
						if( nRet != SOCKET_ERROR && nRet > 0 )
						{
							fwrite( (char *)m_szDataInBuffer, sizeof( char ), nRet, m_pXferFilePointer );
						}
					} while( nRet != SOCKET_ERROR && nRet > 0 ); 
					fclose(m_pXferFilePointer);
					m_bFileHasBeenSaved = TRUE;
					m_bSavingFile = FALSE;
					m_pXferFilePointer = NULL;
					EndWaitCursor(); // kill hourglass 
				}
				else if( !bCancel && m_nRadioASCII )
				{
					// an ASCII store to disk
					BeginWaitCursor(); // show hourglass 
					m_pXferFilePointer = fopen( (const char *)m_sExportFileName, "w" );
					ASSERT( m_pXferFilePointer );
					do
					{
						memset(m_szDataInBuffer,0,NUM1024+2);
						// this memset trick avoids having strtok insert a wild \0 somewhere bad
						//		it is guaranteed to find a \n (the delimiter in this case) before
						//		running off into other memory
						memset(m_szDataInBuffer+NUM1024, '\n', 1); 

						nRet = recv( m_sktData, m_szDataInBuffer, NUM1024, 0 );
						if( nRet != SOCKET_ERROR && nRet > 0 )
						{
							str=strtok(m_szDataInBuffer,"\n");
							while( str && *str)
							{
								char temp[NUM1024+1];
								strcpy( temp, str);
								nLen = strlen(str);
								if( nLen > 0 )
								{
									if( *( str + nLen - 1 ) == 0x0d) // remove the 0x0d aka \r
									{
										*( str + nLen - 1 ) = 0;
										fprintf( m_pXferFilePointer, "%s\n", str );
									}
									else
									{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -