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

📄 filetranssvrview.cpp

📁 文件传送协议的服务器端和客户端源码
💻 CPP
字号:
// FileTransSvrView.cpp : implementation of the CFileTransSvrView class
//

#include "stdafx.h"
#include "FileTransSvr.h"

#include "FileTransSvrDoc.h"
#include "FileTransSvrView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CFileTransSvrView

typedef struct{
	char packetType;     //r:request rootdriver,d:directory f:file D:data
	unsigned int length;
	char content[2000];
}DATA_PACKET;

long sendFileLen=0l;
CCriticalSection critSection;

IMPLEMENT_DYNCREATE(CFileTransSvrView, CFormView)

BEGIN_MESSAGE_MAP(CFileTransSvrView, CFormView)
	//{{AFX_MSG_MAP(CFileTransSvrView)
	ON_BN_CLICKED(IDC_STARTSVR, OnStartsvr)
	ON_MESSAGE(WM_THREADMSG, ThreadRet)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFileTransSvrView construction/destruction

CFileTransSvrView::CFileTransSvrView()
	: CFormView(CFileTransSvrView::IDD)
{
	//{{AFX_DATA_INIT(CFileTransSvrView)
	m_Tips = _T("");
	//}}AFX_DATA_INIT
	// TODO: add construction code here
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD( 2, 2 );
	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return;
	}
	
	if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) {
		WSACleanup( );
		return; 
	}
}

CFileTransSvrView::~CFileTransSvrView()
{
}

void CFileTransSvrView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFileTransSvrView)
	DDX_Control(pDX, IDC_IPADDRESS1, m_IpAddress);
	DDX_Text(pDX, IDC_ETIPS, m_Tips);
	//}}AFX_DATA_MAP
}

BOOL CFileTransSvrView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFormView::PreCreateWindow(cs);
}

void CFileTransSvrView::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();

	m_IpAddress.SetWindowText("127.0.0.1");
}

/////////////////////////////////////////////////////////////////////////////
// CFileTransSvrView printing

BOOL CFileTransSvrView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CFileTransSvrView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CFileTransSvrView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

void CFileTransSvrView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
	// TODO: add customized printing code here
}

/////////////////////////////////////////////////////////////////////////////
// CFileTransSvrView diagnostics

#ifdef _DEBUG
void CFileTransSvrView::AssertValid() const
{
	CFormView::AssertValid();
}

void CFileTransSvrView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}

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

/////////////////////////////////////////////////////////////////////////////
// CFileTransSvrView message handlers

void CFileTransSvrView::OnStartsvr() 
{
	// TODO: Add your control notification handler code here
	CString strIP;
	DWORD dwAddress;
	m_IpAddress.GetAddress(dwAddress);
	strIP.Format("%d.%d.%d.%d",   
		HIBYTE(HIWORD(dwAddress)),   
		LOBYTE(HIWORD(dwAddress)),   
		HIBYTE(LOWORD(dwAddress)),   
		LOBYTE(LOWORD(dwAddress))   
		);

	SOCKET sListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(1032);
	sin.sin_addr.S_un.S_addr=inet_addr(strIP);

	if(::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
	{
		MessageBox("Bind failure!","Error",MB_OK);
		closesocket(sListen);
	}
	else 
	{
		m_Tips="Server has started,binded succeed.";
		UpdateData(false);
	}

	::listen(sListen,5);

	DWORD dwThread;
	::CreateThread(NULL,0,ThreadSelect,(LPVOID)sListen,0,&dwThread);

	//HWND hWnd = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
	//::ShowWindow( hWnd,SW_MINIMIZE );

}

DWORD WINAPI CFileTransSvrView::ThreadSelect(LPVOID lpParameter)
{
	SOCKET sListen=(SOCKET)lpParameter;
	fd_set fdSocket;
	FD_ZERO(&fdSocket);
	FD_SET(sListen,&fdSocket);

	timeval timeout;
	timeout.tv_sec=5;

	while(true)
	{
		fd_set fdRead=fdSocket;
		int nRet=::select(0,&fdRead,NULL,NULL,NULL);
		if(nRet>0)
		{
			for(int i=0;i<(int)fdSocket.fd_count;i++)
			{	if(FD_ISSET(fdSocket.fd_array[i],&fdRead))				
				{	if(fdSocket.fd_array[i]==sListen)			
					{	
						CString strIP;
						sockaddr_in addrRemote;
						int nAddrLen=sizeof(addrRemote);
						SOCKET sNew=::accept(sListen,(sockaddr*)&addrRemote,&nAddrLen);
						FD_SET(sNew,&fdSocket);
						strIP.Format( "%s",inet_ntoa(addrRemote.sin_addr) );

					}
					else
					{
						DATA_PACKET recvPacket;
						int nRecev=::recv(fdSocket.fd_array[i],(char*)&recvPacket,
							sizeof(recvPacket),0);
						if(nRecev>0)
						{
							//Parameters declared following are for switch
							int dchnum;
							char* pDrivesString;
							CString requestPath,retArrFiles[200];
						
							switch(recvPacket.packetType)
							{
							case 'r':      //Send logical drives after "my computer"
								pDrivesString=GetDrivesString();
								memcpy(recvPacket.content,pDrivesString,64);
								recvPacket.length=64;
								::send(fdSocket.fd_array[i],(char*)&recvPacket,
									sizeof(recvPacket),0);
								break;

							case 'd':       //Send directory
                                requestPath=FormatPath(recvPacket.content,recvPacket.length);
								pDrivesString=new char[2000];
                                if( (recvPacket.length=GetDirectoryString(retArrFiles,requestPath,pDrivesString))!=0 )
								{
									recvPacket.packetType='d';
									//memset(recvPacket.content,0,sizeof(recvPacket.content));
									memcpy( recvPacket.content,pDrivesString,2000 );
									::send(fdSocket.fd_array[i],(char*)&recvPacket,
										sizeof(recvPacket),0);
								}
								break;	

							case 'f':       //Send file size
                                requestPath=FormatPath(recvPacket.content,recvPacket.length);
								recvPacket.length=GetFileLength(requestPath);
								recvPacket.packetType='f';
								::send(fdSocket.fd_array[i],(char*)&recvPacket,
									sizeof(recvPacket),0);
								break;

							case 'D':       //Send file data
								dchnum=recvPacket.length;   
								requestPath=FormatPath(recvPacket.content,recvPacket.length);
								SendFile(fdSocket.fd_array[i],dchnum,requestPath);
								break;
							default:
								break;
							}
	
						}
						else
						{
							::closesocket(fdSocket.fd_array[i]);
							FD_CLR(fdSocket.fd_array[i],&fdSocket);
						}
					}
				}
			}
		}
		else{
			//	AfxMessageBox("Select failure");
				break;
			}
	}
	return 0;
}

char* CFileTransSvrView::GetDrivesString()
{
	char* pRet;

	char  szDrives[128];
	if ( !GetLogicalDriveStrings( sizeof(szDrives), szDrives ) )
	{
		return NULL;
	}

	pRet=szDrives;
	return pRet;

}

int CFileTransSvrView::GetDirectoryString(CString retArrFiles[],CString directoryPath,char *pRet)
{
	//AfxMessageBox(directoryPath);     //Check the directoryPath after formatted.
	int arrIndex=0;
	directoryPath+="\\*.*";

	CFileFind finder;
	BOOL bWorking = finder.FindFile(directoryPath);
	if(!bWorking)
	{
		memcpy( pRet,"NULL",strlen("NULL") );
		return strlen("NULL");
	}

	while( bWorking&&arrIndex<200)
	{
		bWorking = finder.FindNextFile();
		retArrFiles[arrIndex] = finder.GetFileName();
		arrIndex++;
	}
	
	// change CString's Array to char's point
	char *pTemp=new char[2000];
	int i=0,j=0;
	while( i<2000 && j<200 && retArrFiles[j]!="" )
	{
		int k=retArrFiles[j].GetLength();
		for( int a=0; a<=k && i<2000; a++ )
		{
			if(a==k)
				pTemp[i]='|';
			else
				pTemp[i]=retArrFiles[j][a];
			i++;
		}
		j++;
	}
	memcpy( pRet,pTemp,2000 );
	
	return i;
}

CString CFileTransSvrView::FormatPath(char chPath[],int length)
{
	int j=0;
	char *pTemp;
	CString strPath;
	pTemp=(LPTSTR)(LPCTSTR)strPath;
	pTemp=new char[64];
	memcpy(pTemp,chPath,64);
	
	while( j<length )
	{
		strPath.Insert( j,pTemp[j] );
		j++;
	}
	delete pTemp;

	return strPath;
}

long CFileTransSvrView::GetFileLength(CString strPath)
{
	long retLength;
    FILE *stream;
	if( (stream  = fopen( strPath, "r" )) == NULL )
		return 0;
	fseek( stream, 0, SEEK_END);
	retLength=ftell( stream );
	fclose( stream );

	return retLength;
}


void CFileTransSvrView::SendFile(SOCKET socket,int segInfo, CString strPath)
{
	char* pSend=new char[2000];
	long fLength = GetFileLength(strPath);    //abtain file size
	int segIndex = segInfo/100 ;
	int thrNum = segInfo - segIndex*100;
	int segLength = fLength/thrNum;
	long bPoint = (segIndex-1)*segLength;

	if( segIndex == thrNum )
		segLength = fLength-bPoint;

	FILE *file;
	if( (file  = fopen( strPath, "rb" )) == NULL )
       AfxMessageBox( "faild to open file!");
	

	DATA_PACKET packSend;
	packSend.packetType='D';

	int process=0,packIndex=1;

	while(segLength>0)           // send file
	{ 
		packSend.length = packIndex;

		critSection.Lock(5000);
		fseek(file,bPoint+(packIndex-1)*2000,SEEK_SET);

		if( segLength<=2000 )
		{
			fread( pSend,1,segLength,file );
			memset( packSend.content,0,2000 );

			memcpy( packSend.content,pSend,segLength );
			send( socket,(char*)&packSend,sizeof(packSend),0 );
			sendFileLen+=segLength;
			if( sendFileLen==fLength )
				fclose(file);
			critSection.Unlock();
			return ;

		}

		fread( pSend,sizeof(char),2000,file );
		memset( packSend.content,0,2000 );
		memcpy( packSend.content,pSend,2000 );
		send( socket,(char*)&packSend,sizeof(packSend),0 );

		sendFileLen+=2000;
		critSection.Unlock();
		//fseek( file,2000,SEEK_CUR );

		packIndex++;
		segLength -= 2000;
	}

}

void CFileTransSvrView::ThreadRet(WPARAM wParam, LPARAM lParam)
{
    char buf[128];
	sprintf(buf,(char*)wParam);
	delete[] (char*)wParam;
	AfxMessageBox(buf);
}

LRESULT CFileTransSvrView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	return CFormView::WindowProc(message, wParam, lParam);
}

⌨️ 快捷键说明

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