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文件运行也是一样的,感兴趣的读者自己分析,我就不在这里累述了,本文章仅仅作为导读,后面的大海,我会继续探险,有兴趣可以一起交流