FileZilla server源码导读

最近在学网络编程,找到了国外一个开源的FTP服务器FileZilla server,可以研究研究源代码,当然开始时候应该要编译成功,下面给大家一个能够编译的版本,

假设你已经在自己机子上安装了vs2010(也许vs2008也可以吧),下载下面的源代码,既然我们看的是开源软件源码,下载当然也是免费的,一起共享

http://download.csdn.net/detail/hellosijian/4691680

解压打开里面的工程,编译就可以,具体用法可以参看下面这篇文章,运行服务器后,可以直接在你的浏览器上输入   ftp:电脑IP便可进入 ,或者打开cmd命令行,输入ftp   ip也可以进入

http://xbeta.info/filezilla-server.htm

看源码用source insight,这里只分析服务器,客户端没研究

源码机构是这样的

interface是另外一个工程,主要是图形界面来管理远程服务器的,先暂时不管它,我们看主要的服务器部分

下面说说服务器是如何启动的

打开Service.cpp这个文件,WinMain函数就在这里,在source insight的左边栏里找到WinMain,开头我们就看到了这段代码

	BOOL bNT = FALSE;
	BOOL bInstalled = FALSE;
	BOOL dwCurrentState = 0;
	
	int nAction = 0;
	if (lpCmdLine[0] == '/' || lpCmdLine[0] == '-')
	{
		lpCmdLine++;
		if (strlen(lpCmdLine) >= 6 && !strncmp(lpCmdLine, "compat", 6))
		{
			lpCmdLine += 6;
			while (lpCmdLine[0] == ' ')
				lpCmdLine++;
			return CompatMain(lpCmdLine);
		}
		else if (!strcmp(lpCmdLine, "install"))
			nAction = 1;
		else if (!strcmp(lpCmdLine, "uninstall"))
			nAction = 2;
		else if (!strcmp(lpCmdLine, "start"))
			nAction = 3;
		else if (!strcmp(lpCmdLine, "stop"))
			nAction = 4;
		else if (!strcmp(lpCmdLine, "install auto"))
			nAction = 5;
		else if (strlen(lpCmdLine) >= 10 && !strncmp(lpCmdLine, "adminport ", 10))
			nAction = 6;
		else if (!strcmp(lpCmdLine, "reload-config"))
			nAction = 7;
		else if (!strncmp(lpCmdLine, "servicename ", 12))
			return SetServiceName(CStdString(lpCmdLine + 12));
		else if (!strncmp(lpCmdLine, "servicedisplayname ", 19))
			return SetServiceDisplayName(CStdString(lpCmdLine + 19));
	}

 其实这段代码是需要通过命令行方式来启动服务器的,当然你也可以双击上面工程目录里面release目录里的exe文件启动,它会弹出几个messgebox询问你的选项,一个简单的

启动服务器的方法时在命令行里面输入

这样就能共启动与关闭服务了,启动之后是妹图形界面的,要用interface里面的管理工具来设置,可以在里面添加一个anonymous的用户名,当然不要设置密码,这样浏览器就能

直接登录进去了,我用的是firefox,如果你用wireshark(国外一个功能非常强大的抓包软件)还能看到三路握手,FTP消息头

 

 跟着源码,输入以上命令后代码进入了CompatMain(lpCmdLine);函数,按ctrl然后鼠标左键跳到该函数定义处,变能看到windows编程里面经典的消息循环,以及服务器socket的创建Cserver.Create();

int CompatMain(LPCSTR lpCmdLine)
{
	int nAction = 0;

	if (lpCmdLine[0] == '/' || lpCmdLine[0] == '-')
	{
		lpCmdLine++;
		if (!strcmp(lpCmdLine, "start"))
			nAction = 1;
		else if (!strcmp(lpCmdLine, "stop"))
			nAction = 2;
		else if (strlen(lpCmdLine) >= 10 && !strncmp(lpCmdLine, "adminport ", 10))
			nAction = 3;
		else if (!strcmp(lpCmdLine, "install"))
			return 0;
		else if (!strcmp(lpCmdLine, "uninstall"))
			return 0;
		else if (!strcmp(lpCmdLine, "install auto"))
			return 0;
		else if (!strcmp(lpCmdLine, "reload-config"))
			nAction = 4;
	}

	if (nAction == 3)
		return SetAdminPort(atoi(lpCmdLine + 10));
	else if (nAction == 4)
		return ReloadConfig();

	HWND hWnd = FindWindow(_T("FileZilla Server Helper Window"), _T("FileZilla Server Helper Window"));
	if (nAction == 1 && hWnd)
		return 0;
	else if (nAction==2 && !hWnd)
		return 0;
	
	if (!hWnd && (nAction == 1 || (nAction == 0 && MessageBox(0, _T("Start Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
	{
		// initialize Winsock library
		BOOL res=TRUE;
		WSADATA wsaData;
		//windows里面socket的初始化
		WORD wVersionRequested = MAKEWORD(1, 1);
		int nResult = WSAStartup(wVersionRequested, &wsaData);
		if (nResult != 0)
			res=FALSE;
		else if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
		{
			WSACleanup();
			res=FALSE;
		}
		
		if(!res)
		{
			return 1;
		}
		//这里便是服务器的创建,跟踪进去我想会是一片海,留待下次再说
		CServer *pServer = new CServer;
		VERIFY(pServer->Create());
		
		MSG msg;
		while (GetMessage(&msg, 0, 0, 0))//经典的windows循环
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		
		delete pServer;
		WSACleanup();
		return 0;
	}		
	else if (hWnd && (nAction == 2 || (nAction == 0 && MessageBox(0, _T("Stop Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
	{
		SendMessage(hWnd, WM_CLOSE, 0, 0);//关闭服务器
		if (GetLastError())
			return 1;
		else
			return 0;
	}
	
	return 1;
}

 我们刚才跟踪的是命令行下的启动工程,双击exe文件运行也是一样的,感兴趣的读者自己分析,我就不在这里累述了,本文章仅仅作为导读,后面的大海,我会继续探险,有兴趣可以一起交流

posted @ 2012-10-27 12:04  godjob  Views(956)  Comments(0Edit  收藏  举报