FTP客户端课程设计报告书模板.doc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- FTP 客户端 课程设计 报告书 模板
- 资源描述:
-
《计算机网络》课程设计 课题名称 FTP用户机搭建 学院 信息工程学院 专业 网络工程 班级 学号 姓名 目录和索引 一、需求分析------------------------------------------2 1、功效需求 2、开发环境和工具 3、所需要知识 二、知识了解 -----------------------------------------2 1、FTP实现基础原理 (1)概要 (2)上传和下载 (3)用户FTP和匿名FTP (4)ASCII和Binary (5)Port和Passive 三、完成进度-----------------------------------------3 1、已完成部分 2、未完成部分 3、还需改善部分 四、FTP服务工作过程---------------------------------4 五、具体设计-----------------------------------------5 1、CFtpDlg类部分函数定义………………………………………………5 2、CFtpOperate部分函数定义……………………………………………17 六、测试结果----------------------------------------29 七、用户手册----------------------------------------32 八、试验总结----------------------------------------32 FTP用户端程序 一、需求分析 1、功效需求 (1)实现一个图形用户界面FTP用户端,确保文件安全传输和存放。 (2)提供登录界面,上传下载界面、帮助界面、相关界面。 (3)经过输入服务器地址、用户名和密码,能够实现远程FTP主机登录。 (4)提供当地文件和文件夹上传功效,可对FTP主机文件进行下载和删除文件。 (5)提供对当地目录读取和返回,能正确列出文件和文件夹,在没有登录服务器前能够作为一个简单文件查询工具对当地文件进行查询。 (6)帮助页面能够对用户提供使用说明。 (7)相关界面包含设计者信息。 (9)要求开发出FTP用户端符合标准FTP协议规范,支持ASCII传输模式和二进制数据传输模式 (10)FTP两种工作模式选择Port模式(主动)和Passive模式(被动) 2、开发环境和工具 (1)使用IDE:使用VC++6.0作为开发环境IDE (2)使用语言:C++ (3)使用开发包:使用MFC和WinInet (4)开发平台:Windows 7 3、所需要知识 (1)计算机网络基础知识 (2)了解FTP基础实现原理 (2)使用VC++6.0IDE进行MFC程序开发基础知识 (3)熟悉WinInet中属于FTP部分操作 (4)熟悉文件或文件夹操作 (5)熟悉控件操作,如在List Ctrol添加图片(浏览文件或文夹图标) 二、知识了解 1、FTP实现基础原理 (1)概要 Internet是一个很复杂计算机环境, Internet上计算机已经有上千万台,而这些计算机可能运行不一样操作系统,有运行Unix服务器,也有运行Dos、WindowsPC机等等,而多种操作系统之间文件交流问题,需要建立一个统一文件传输协议,这就是所谓FTP。基于不一样操作系统有不一样FTP应用程序,而全部这些应用程序全部遵守同一个协议,这么用户就能够把自己文件传送给她人,或从其它用户环境中取得文件。 FTP也是一个用户机/服务器系统。用户经过一个支持FTP协议用户机程序,连接到在远程主机上FTP服务器程序。用户经过用户机程序向服务器程序发出命令,服务器程序实施用户所发出命令,并将实施结果返回到用户机。使用FTP时必需首先登录,在远程主机上取得对应权限以后,方可下载或上传文件。 (2)上传和下载 "下载"文件就是从远程主机拷贝文件至自己计算机上; "上传"文件就是将文件从自己计算机中拷贝至远程主机上 (3)用户FTP和匿名FTP 用户FTP: 种方法为已在FTP服务器上建立了特定帐号用户使用,需要正当用户名和密码才能登录到远程计算机传输文件。 匿名FTP:用户作为“anonymous” 登录到FTP服务器,不需要有自己用户名和密码。 (4)ASCII和Binary ASCII: 文本传输器使用ASCII字符,并由回车键和换行符分开 Binary:二进制不用转换或格式化就可传字符,二进制模式比文本模式愈加快,而且能够传输全部ASCII值,所以系统管理员通常将FTP设置成二进制模式。 (5)Port和Passive Port模式( 主动):FTP 用户端首先和FTP服务器TCP 21端口建立连接,经过这个通道发送命令,用户端需要接收数据时候在这个通道上发送PORT命令。 PORT命令包含了用户端用什么端口接收数据。在传送数据时候,服务器端经过自己TCP 20端口连接至用户端指定端口发送数据。 FTP server必需和用户端建立一个新连接用来传送数据。 Passive模式(被动):Passive模式在建立控制通道时候和Standard模式类似,但建立连接后发送不是Port命令,而是Pasv命令。FTP服务器收到Pasv命令后,随机打开一个高端端口(端口号大于1024)而且通知用户端在这个端口上传送数据请求,用户端连接FTP服务器此端口,然后FTP服务器将经过这个端口进行数据传送,这个时候FTP server不再需要建立一个新和用户端之间连接。 三、完成进度 1、已完成部分 (1)实现一个图形用户界面FTP用户端,确保文件安全传输和存放。 (2)提供登录界面,上传下载界面、帮助界面、相关界面 (3)经过输入服务器地址、用户名和密码,能够实现远程FTP主机登录。 (4)提供当地文件上传功效,可对FTP主机文件进行下载和删除文件。 (5)提供对当地目录读取和返回,能正确列出文件和文件夹,在没有登录服务器前能够作为一个简单文件查询工具对当地文件进行查询。 (6)帮助页面能够对用户提供使用说明。 (7)相关界面包含设计者信息(帮助界面和相关界面整合在一起)。 (9)支持ASCII传输模式和二进制数据传输模式,外加自动选择模式 (10)FTP两种工作模式选择Port模式(主动)和Passive模式(被动) (11)提供用户操作状态信息输出 2、未完成部分 只提供了当地文件上传功效,临时不能提供文件夹上传功效,因为当初没有使用多线程对服务器端进行操作,若上传或下载文件过大,会造成界面陷入长时间不响应中。因为时间问题,就不再进行多线程扩充,也就不提供文件夹上传功效。 3、还需改善部分 (1)使用多线程进行操作 (2)提供文件夹上传和文件夹下载功效 (3)改善界面,提供更方便操作 (4)增加上传和下载队列 (5)同时可连接多个FTP服务器 (6)改善提醒信息 (7)账户。密码等用户资料在当地加密后保留 (8)增加更多功效,以下载完成后关机等 (9)等……… 四、FTP服务工作程 五、具体设计 (1)CFtpDlg类部分函数定义 BOOL CFtpDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE); m_ctrBinary.SetCheck(1); m_ctrActive.SetCheck(1); m_editPort.SetWindowText("21"); bBinary1 = 1; // 使用二进制 bPassive1 = 0; // 使用主动 myPort = 21; m_imgList.Create(20,20,ILC_COLOR32,0,0); // 创建图像列表 m_imgList.SetBkColor(RGB(255,255,255)); // 文件夹图标 hIconFold = ::LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_FOLDER)); // 文件图标 hIconFile = ::LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_FILE)); m_imgList.Add(hIconFold); m_imgList.Add(hIconFile); m_ctrlLocalFile.SetImageList(&m_imgList,LVSIL_SMALL); // 关联 m_ctrlServerFile.SetImageList(&m_imgList,LVSIL_SMALL); // 关联 m_editServer.SetWindowText("ftp:// "); m_editName.SetWindowText(""); m_editPassword.SetWindowText(""); m_btnCon.EnableWindow(TRUE); m_btnClo.EnableWindow(FALSE); m_ctrlLocalFile.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); m_ctrlServerFile.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); m_ctrlLocalFile.InsertColumn(0,"文件名",LVCFMT_LEFT,140,0);//设置列 m_ctrlLocalFile.InsertColumn(1,"文件类型",LVCFMT_LEFT,100,1); m_ctrlLocalFile.InsertColumn(2,"修改日期",LVCFMT_LEFT,100,2); m_ctrlServerFile.InsertColumn(0,"文件名",LVCFMT_LEFT,140,0);//设置列 m_ctrlServerFile.InsertColumn(1,"文件类型",LVCFMT_LEFT,100,1); m_ctrlServerFile.InsertColumn(2,"修改日期",LVCFMT_LEFT,100,2); // 添加硬盘盘符 size_t szAllDriveStrings=::GetLogicalDriveStrings(0,NULL); TCHAR *pDriveStrings=new TCHAR[szAllDriveStrings+sizeof(_T(" "))]; GetLogicalDriveStrings(szAllDriveStrings,pDriveStrings); size_t szDriveString=::strlen(pDriveStrings); while(szDriveString>0) { m_ctrlLocal.AddString(pDriveStrings); pDriveStrings+=szDriveString+1; szDriveString=::strlen(pDriveStrings); } int index = m_ctrlLocal.FindString(0,"c:\\"); m_ctrlLocal.SetCurSel(index); m_strLocPath = "c:\\"; // 初始化为c盘 ListLocFile(); cFtpOpr.setEidt(&m_ediMessage); return TRUE; // return TRUE unless you set the focus to a control } void CFtpDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } void CFtpDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CFtpDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } // 连接服务器 void CFtpDlg::OnBtnConnect() { // TODO: Add your control notification handler code here m_editServer.GetWindowText(m_strServer); // 统计FTP服务器地址 CString strtemp; m_editPort.GetWindowText(strtemp); myPort = ::atoi(strtemp); // 取得设置端口号 int i; if (bAnony == 0) {// 不使用匿名 m_editName.GetWindowText(m_strName); // 统计FTP登陆用户名 m_editPassword.GetWindowText(m_strPassword); // 统计FTP登陆用户密码 i = cFtpOpr.set(m_strServer,m_strName,m_strPassword); } else {// 使用匿名 CString strNameTemp; m_editName.GetWindowText(strNameTemp); // 匿名登陆用户名 i = cFtpOpr.set(m_strServer,strNameTemp,""); } if (i) {// 设置成功,打开连接 if (cFtpOpr.OpenConnection()) {// 连接成功 m_btnClo.EnableWindow(TRUE); m_btnCon.EnableWindow(FALSE); UpdateServerFile();// 更新服务器文件显示 m_ctrlServer.ResetContent(); CString temp; cFtpOpr.GetPath(temp); m_ctrlServer.AddString((LPSTR)(LPCTSTR)temp); m_ctrlServer.SetCurSel(0); m_chkAnony.EnableWindow(FALSE); m_ctrActive.EnableWindow(FALSE); CButton *temp2 =(CButton*)GetDlgItem(IDC_PASSIVE); temp2->EnableWindow(FALSE); m_editPort.EnableWindow(FALSE); } else { // 连接失败 } } } void CFtpDlg::OnBtnClose() {// 关闭连接 if (cFtpOpr.CloseConnection()) {// 关闭成功 m_btnClo.EnableWindow(FALSE); m_btnCon.EnableWindow(TRUE); m_ctrlServerFile.DeleteAllItems(); m_ctrlServer.ResetContent(); m_ctrActive.EnableWindow(TRUE); CButton *temp2 =(CButton*)GetDlgItem(IDC_PASSIVE); temp2->EnableWindow(TRUE); m_editPort.EnableWindow(TRUE); m_chkAnony.EnableWindow(TRUE); } } // 双击当地文件列表控件中选项 void CFtpDlg::OnDblclkListLocalfile(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here POSITION p=m_ctrlLocalFile.GetFirstSelectedItemPosition(); if (p == NULL) { return; } //获取刚选择位置下标(从0开始) int index = m_ctrlLocalFile.GetNextSelectedItem(p); //取得选中内容 //得到第index行.第0列内容(下标从0开始) CString FirstColumn=m_ctrlLocalFile.GetItemText(index,0); CString SecondColumn = m_ctrlLocalFile.GetItemText(index,1); if (index == 0) // 返回上层目录 { int k = m_strLocPath.GetLength() - 1; if (m_strLocPath.Right(2) == ":\\") { return; } // 删除当层项目 int ix = m_ctrlLocal.FindString(0,m_strLocPath); if (ix != CB_ERR) { m_ctrlLocal.DeleteString(ix); } for (int j = k -1; j >= 2;--j) { if (m_strLocPath.GetAt(j) == '\\') { m_strLocPath = m_strLocPath.Left(j+1); break; } } ListLocFile(); *pResult = 0; return; } if (SecondColumn=="文件夹") { CString strTemp = FirstColumn; m_strLocPath += strTemp + '\\'; ListLocFile(); // 更新当地磁盘文件显示 } else if (SecondColumn=="文件") {// 点到是文件,进行上传 if (cFtpOpr.ReStatus()==2) { cFtpOpr.PutFtpFile(m_strLocPath + FirstColumn,FirstColumn); UpdateServerFile();// 更新服务器文件显示 } } *pResult = 0; } void CFtpDlg::OnDblclkListServerfile(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here //获取选中一个位置 POSITION p=m_ctrlServerFile.GetFirstSelectedItemPosition(); if (p == NULL) { return; } //获取刚选择位置下标(从0开始) int index = m_ctrlServerFile.GetNextSelectedItem(p); //取得选中内容,得到第index行.第0列内容(下标从0开始) CString FirstColumn=m_ctrlServerFile.GetItemText(index,0); CString SecondColumn = m_ctrlServerFile.GetItemText(index,1); CStringArray ServName; int nFileNumber=0; if (index == 0) // 返回上层目录 { if (cFtpOpr.setBackPath() == 0) { *pResult = 0; return; } UpdateServerFile();// 更新服务器文件显示 CString temp; m_ctrlServer.ResetContent(); cFtpOpr.GetPath(temp); m_ctrlServer.AddString((LPSTR)(LPCTSTR)temp); m_ctrlServer.SetCurSel(0); *pResult = 0; return; } if (SecondColumn=="文件夹") { if (cFtpOpr.setNextPath(FirstColumn) == 0) { *pResult = 0; return; } UpdateServerFile();// 更新服务器文件显示 CString temp; m_ctrlServer.ResetContent(); cFtpOpr.GetPath(temp); m_ctrlServer.AddString((LPSTR)(LPCTSTR)temp); m_ctrlServer.SetCurSel(0); } else if (SecondColumn=="文件") {// 点到是文件,进行下载 cFtpOpr.GetFtpFile(FirstColumn,m_strLocPath); ListLocFile(); } *pResult = 0; } // 将当地文件列表出来 void CFtpDlg::ListLocFile() { m_ctrlLocalFile.DeleteAllItems(); int ix = m_ctrlLocal.FindString(0,m_strLocPath); if (ix == CB_ERR) { int iy = m_ctrlLocal.GetCount(); m_ctrlLocal.SetCurSel(m_ctrlLocal.AddString(m_strLocPath)); } else { m_ctrlLocal.SetCurSel(m_ctrlLocal.SetCurSel(ix)); } int k = 0; m_ctrlLocalFile.InsertItem(0,"...上层目录"); char * lpPath = (LPSTR)(LPCTSTR)m_strLocPath; char szFind[300]; WIN32_FIND_DATA FindFileData; strcpy(szFind,lpPath); strcat(szFind,"*.*"); HANDLE hFind=::FindFirstFile(szFind,&FindFileData); while(TRUE) { if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { CString str = FindFileData.cFileName; if (str != '.' && str != "..") { LVITEM lvitem; lvitem.mask = LVIF_IMAGE|LVIF_TEXT; lvitem.iItem = k+1; lvitem.pszText = (LPSTR)(LPCTSTR)str; lvitem.iImage = 0; lvitem.iSubItem =0; m_ctrlLocalFile.InsertItem(&lvitem); m_ctrlLocalFile.SetItemText(k+1,1,"文件夹"); ++k; } } else { // 文件 LVITEM lvitem; lvitem.mask = LVIF_IMAGE|LVIF_TEXT; lvitem.iItem = k+1; lvitem.pszText = FindFileData.cFileName; lvitem.iImage = 1; lvitem.iSubItem = 0; m_ctrlLocalFile.InsertItem(&lvitem); m_ctrlLocalFile.SetItemText(k+1,1,"文件"); ++k; } if(!FindNextFile(hFind,&FindFileData))break; } FindClose(hFind); } // 选择了当地文件组合框中不一样项目 void CFtpDlg::OnSelchangeComboboxexLocal() { m_ctrlLocal.SetCurSel(m_ctrlLocal.GetCurSel()); m_ctrlLocal.GetWindowText(m_strLocPath); m_ctrlLocal.ResetContent(); // 添加硬盘盘符 size_t szAllDriveStrings=::GetLogicalDriveStrings(0,NULL); TCHAR *pDriveStrings=new TCHAR[szAllDriveStrings+sizeof(_T(" "))]; GetLogicalDriveStrings(szAllDriveStrings,pDriveStrings); size_t szDriveString=::strlen(pDriveStrings); while(szDriveString>0) { m_ctrlLocal.AddString(pDriveStrings); pDriveStrings+=szDriveString+1; szDriveString=::strlen(pDriveStrings); } ListLocFile(); } // 点击了ASCII单选按钮 void CFtpDlg::OnAscii() { bBinary1 = 0; } // 点击了二进制单选按钮 void CFtpDlg::OnBinary() { bBinary1 = 1; // 使用二进制 } // 自动选择二进制或ASCII单选按钮 void CFtpDlg::OnAuto() { bBinary1 = 2; // 自动 } // 主动方法单选按钮 void CFtpDlg::OnActive() { bPassive1 = 0; } // 被动方法单选按钮 void CFtpDlg::OnPassive() { bPassive1 = 1; } // 上传 void CFtpDlg::OnBtnup() { POSITION p=m_ctrlLocalFile.GetFirstSelectedItemPosition(); if (p == NULL) { return; } //获取刚选择位置下标(从0开始) int index = m_ctrlLocalFile.GetNextSelectedItem(p); //取得选中内容 //得到第index行.第0列内容(下标从0开始) CString FirstColumn=m_ctrlLocalFile.GetItemText(index,0); CString SecondColumn = m_ctrlLocalFile.GetItemText(index,1); if (SecondColumn=="文件夹") { CTime CurrentTime=CTime::GetCurrentTime(); CString strTime; strTime.Format("%d/%d/%d %d:%d:%d ",CurrentTime.GetYear(),CurrentTime.GetMonth(), CurrentTime.GetDay(),CurrentTime.GetHour(), CurrentTime.GetMinute(), CurrentTime.GetSecond()); strTime += "暂不支持上传文件夹!\r\n"; int nLength = m_ediMessage.SendMessage(WM_GETTEXTLENGTH); m_ediMessage.SetSel(nLength, nLength); m_ediMessage.ReplaceSel(strTime); return; } else if (SecondColumn=="文件") { // 点到是文件,进行上传 if (cFtpOpr.ReStatus()==2) { cFtpOpr.PutFtpFile(m_strLocPath + FirstColumn,FirstColumn); UpdateServerFile();// 更新服务器文件显示 } } } //下载 void CFtpDlg::OnBtndown() { // TODO: Add your control notification handler code here POSITION p=m_ctrlServerFile.GetFirstSelectedItemPosition(); if (p == NULL) { return; } //获取刚选择位置下标(从0开始) int index = m_ctrlServerFile.GetNextSelectedItem(p); //取得选中内容 //得到第index行.第0列内容(下标从0开始) CString FirstColumn=m_ctrlServerFile.GetItemText(index,0); CString SecondColumn = m_ctrlServerFile.GetItemText(index,1); if (SecondColumn=="文件夹") { CTime CurrentTime=CTime::GetCurrentTime()展开阅读全文
咨信网温馨提示:1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。




FTP客户端课程设计报告书模板.doc



实名认证













自信AI助手
















微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/2657842.html