FTP协议实验报告
- 格式:docx
- 大小:63.45 KB
- 文档页数:17
计算机网络原理FTP实验报告XXXXXXXXXXXXXXXXX1.实验综述:本实验中,笔者通过Socket编程实现了一个简单的FTP协议。
实现的程序包括客户端(client.cpp)和服务端(server.cpp)两个部分,并支持如下功能:(1)GET命令(下载服务端文件到客户端所在目录);(2)PUT命令(上传客户端文件到服务端工作目录);(3)PWD命令(打印服务端工作目录);(4)DIR命令(列出服务端工作目录下的文件);(5)CD命令(改变服务端工作目录);(6)?命令(查看帮助);(7)QUIT命令(关闭客户端与服务端的控制连接并退出客户端和服务端)。
上述支持的命令中,除?命令和QUIT命令外,命令执行时,客户端会先与服务端建立数据连接,在数据连接上完成传输后再断开设计连接,从而实现了FTP协议的设计思想。
最终实验程序能够正确完成FTP协议基本的文件传输功能,对较大的文件同样支持,符合本实验的要求。
2.设计思路说明:本实验的两个核心是FTP连接模型的建立和文件、数据的传输,笔者对二者的实现思路分别如下所述。
FTP的连接建立过程如下:(1)服务器启动后,建立控制连接Socket并监听控制连接端口;(2)客户端启动并连接至该端口;(3)服务器接受来自客户端的连接,此时控制连接建立;(4)服务器建立数据连接Socket,将其绑定在数据连接端口上并监听;(5)客户端每接收到除?命令和QUIT命令外的任一命令时,判定命令格式是否合法,将合法的命令发送到服务器,等待来自服务器的响应;(6)服务器接收到命令后,监听数据连接端口等待连接,通过控制连接向客户端发送响应后等待客户连接至数据端口;(7)客户端接收到响应后,连接到数据端口,等待来自服务器的响应;(8)服务器接受来自客户端的连接,此时数据连接建立。
服务器通过数据连接向客户端发送响应;(9)客户端接收到响应后,开始数据传输操作;(10)数据传输完成后,客户端关闭数据Socket,服务端关闭接收客户端数据连接所得的Socket;(11)客户端接收到QUIT命令时,将命令发送给服务器后,关闭控制连接Socket 并退出;服务器接收到QUIT命令时,关闭自身的控制连接Socket、自身的数据连接Socket并退出。
工程类实验报告系:网络工程专业:网络工程年级: 2009 姓名:学号:实验课程:网络协议分析实验室号:____田C510__ 实验设备号:实验时间: 12.26指导教师签字:成绩:实验四 FTP 协议分析实验一、实验目的和要求学习 Serv-U FTP Server 服务软件的基本配置和 FTP 客户端命令的使用,分析FTP 报文格式和 FTP 协议的工作过程。
二、实验原理FTP 是文件传输协议(File Transfer Protocol)的简称。
FTP 基于 TCP 协议,它通过两个 TCP 连接来传输一个文件,一个是控制连接,另一个是数据连接。
相应的,在进行文件传输时,FTP 需要两个端口,分别用于控制连接端口(用于给服务器发送指令以及等待服务器响应)和数据传输端口(在客户机和服务器之间发送一个文件或目录列表)。
两种连接的建立都要经过一个“三次握手”的过程,同样,连接释放也要采用“四次握手”方法。
控制连接在整个回话期间一直保持打开状态。
数据连接是临时建立的,在文件传送结束后被关闭。
FTP 的连接模式有两种,PORT 和 PASV。
PORT 模式是一个主动模式,PASV 是被动模式,这里都是相对于服务器而言的。
当 FTP 客户以 PORT 模式连接服务器时,它首先动态地选择一个端口号连接服务器的 21 端口,注意这个端口号一定是 1024 以上的,因为 1024 以前的端口都已经预先被定义好,被一些典型的服务使用或保留给以后会用到这些端口的资源服务。
经过 TCP 的三次握手后,控制连接被建立。
这时客户就可以利用这个连接向服务器发送指令和等待服务器响应了。
当需要从(或向)服务器传送数据时,客户会发出 PORT 指令告诉服务器用自己的那个端口来建立一条数据连接(这个命令由控制连接发送给服务器),当服务器接到这一指令时,会使用 20 端口连接客户指定的端口号,用以数据传送。
当FTP 客户以 PASV 模式连接服务器时,控制连接的建立过程与 PORT 模式相同,不同的是,在数据传送时,客户不向服务器发送 PORT 指令而是发送 PASV 指令,服务器收到 PASV命令后选择一个端口号发送给客户,客户选择一个本地端口号与服务器发送过来的端口建立一条数据连接。
一、实验目的1. 理解文件传送协议的基本原理和流程。
2. 掌握常用的文件传送协议,如FTP、TFTP等。
3. 学习使用文件传送协议进行文件的上传和下载。
4. 了解文件传送协议在实际应用中的优势和局限性。
二、实验环境1. 操作系统:Windows 102. 软件环境:Cygwin、FTP Server、FTP Client3. 网络环境:局域网三、实验内容1. FTP协议实验2. TFTP协议实验四、实验步骤1. FTP协议实验(1)搭建FTP服务器1)在Cygwin中安装FTP服务器。
2)配置FTP服务器,设置用户名和密码。
3)启动FTP服务器。
(2)使用FTP客户端连接FTP服务器1)在Cygwin中安装FTP客户端。
2)使用FTP客户端连接到FTP服务器。
3)登录FTP服务器。
(3)上传和下载文件1)在FTP客户端选择要上传的文件。
2)使用FTP客户端将文件上传到FTP服务器。
3)在FTP客户端选择要下载的文件。
4)使用FTP客户端将文件从FTP服务器下载到本地。
2. TFTP协议实验(1)搭建TFTP服务器1)在Cygwin中安装TFTP服务器。
2)配置TFTP服务器,设置共享目录。
3)启动TFTP服务器。
(2)使用TFTP客户端连接TFTP服务器1)在Cygwin中安装TFTP客户端。
2)使用TFTP客户端连接到TFTP服务器。
(3)上传和下载文件1)在TFTP客户端选择要上传的文件。
2)使用TFTP客户端将文件上传到TFTP服务器。
3)在TFTP客户端选择要下载的文件。
4)使用TFTP客户端将文件从TFTP服务器下载到本地。
五、实验结果与分析1. FTP协议实验实验结果表明,使用FTP协议可以方便地进行文件的上传和下载。
FTP服务器和客户端的配置较为简单,易于操作。
但在实际应用中,FTP协议存在以下局限性:(1)FTP协议不是加密传输,存在安全隐患。
(2)FTP协议传输速度较慢。
(3)FTP协议不支持断点续传。
FTP实验报告1、实验目的本实验要求在linux系统上完成一个文件传输协议,通过本实验,不但可以深入理解FTP协议的原理和细节,还可以学会利用Socket接口设计实现简单应用层协议,掌握网络应用程序的基本设计方法和实验技巧。
2、实验说明文件传输协议用于两台计算机之间传递文件,FTP包含了两个通道。
一个是控制通道,一个是数据通道。
控制通道是和FTP服务器进行沟通的通道,连接服务器,发送指令。
数据通道则是和FTP服务器进行文件传输和获取文件列表的通道。
3、实验内容本实验要求在Linux系统上使用Socket接口实现FTP客户顿和服务器端的程序,使客户端可以连接至服务器,并且可以进行一些FTP的基本操作。
应实现的FTP命令包括如下几点:1、 get: 取远方的一个文件2、 put: 传给远方一个文件3、 pwd: 显示远方当前目录 4、 dir: 列出远方当前目录 5、 cd: 改变远方当前目录 6、 help: 显示提供的命令 7、 quit: 退出4、实验代码客户端和服务器代码见附件。
5、思考题1.在FTP协议中,为什么要建立两个TCP连接来分别传送命令和数据?答:如果只用一个连接,那就是复用一个端口。
而我们知道,端口之间通信需要传输协议才能建立连接,端口的复用等于说在一个端口上同时使用2种协议以上,但如果是10种协议呢?不但会影响传输速度,数据出错的概率也变大了。
2.主动方式和被动方式的主要区别是什么?为何要设计这两种方式?答:区别:主动方式下客户端首先和服务端建立连接,在传输数据时服务器和客户端必须建立一个新的连接,而被动方式则是由服务器等待客户端来连接,且不用建立新的连接。
原因:一般情况下都是采用主动模式,但很多防火墙在设置的时候都是不允许接受外部发起的连接的,所以主动模式许多时候在内部网络的机器通过防火墙出去时受到了限制,因为从服务器的TCP 20无法和内部网络的客户端建立一个新的连接,造成无法工作。
ftp实验报告FTP实验报告一、引言FTP(File Transfer Protocol,文件传输协议)是一种用于在网络上进行文件传输的标准协议。
它基于客户端-服务器模型,通过在客户端和服务器之间建立连接,实现文件的上传和下载。
本实验旨在通过搭建FTP服务器和客户端,探索FTP协议的工作原理,并测试其性能和稳定性。
二、实验环境和工具本次实验使用的环境是一台Windows操作系统的计算机,实验工具包括FileZilla Server和FileZilla Client。
三、实验步骤1. 搭建FTP服务器首先,在计算机上安装FileZilla Server软件。
安装完成后,打开软件并进行配置。
配置包括设置服务器的监听IP地址和端口号,设置用户账号和密码,以及设置共享文件夹的路径。
配置完成后,启动FTP服务器。
2. 配置FTP客户端在另一台计算机上安装FileZilla Client软件。
安装完成后,打开软件并进行配置。
配置包括设置FTP服务器的地址、端口号、用户名和密码。
配置完成后,连接到FTP服务器。
3. 文件上传和下载在FTP客户端上,选择需要上传的文件,并将其拖拽到服务器的文件列表中。
文件上传完成后,可以在服务器端的共享文件夹中看到该文件。
同样地,在FTP客户端上选择需要下载的文件,并将其拖拽到本地文件列表中。
文件下载完成后,可以在本地计算机的指定位置找到该文件。
四、实验结果和分析1. 性能测试在实验过程中,我们测试了FTP协议的性能。
通过上传和下载不同大小的文件,我们记录了文件传输所需的时间,并计算了传输速度。
实验结果显示,随着文件大小的增加,传输速度逐渐下降。
这是因为较大的文件需要更多的时间来传输,而网络带宽是有限的。
2. 稳定性测试我们还测试了FTP协议的稳定性。
在大量并发上传和下载文件的情况下,观察FTP服务器和客户端的响应情况。
实验结果显示,当并发操作过多时,FTP 服务器的响应时间会增加,甚至出现连接超时的情况。
FTP实验心得
最近我进行了一次FTP实验,对这一互联网传输协议有了更深入的理解。
这次实验让我对FTP在实际应用中的重要性有了新的认识,也让我对网络传输和数据交换有了更直观的体验。
在实验中,我了解了FTP的基本概念和工作原理。
FTP,即文件传输协议,是一种用于在网络之间传输文件的协议。
通过FTP,用户可以在不同的计算机之间传输文件,从而实现数据的共享和交换。
在实验过程中,我学习了如何设置FTP服务器和客户端,如何进行文件的上传和下载等操作。
在实践中,我深刻感受到了FTP的便利性和实用性。
通过FTP,我们可以轻松地实现大量数据的快速传输,而且可以保证数据的完整性和安全性。
同时,FTP 还支持多种传输模式,可以根据实际需求进行选择。
在实验过程中,我也遇到了一些问题,比如权限设置、文件传输速度慢等。
但是通过查阅资料和请教老师,我最终成功解决了这些问题。
通过这次实验,我对计算机网络有了更深入的了解,也提高了自己的动手能力和解决问题的能力。
同时,我也认识到了网络安全和数据保护的重要性。
在未来的学习和工作中,我将继续关注网络技术的发展,努力提高自己的技术水平和实践能力。
文件传输协议F T P服务配置实验work Information Technology Company.2020YEAR昆明理工大学(计算机网络)实验报告实验名称文件传输协议FTP服务配置实验实验时间 2012 年 5 月日专业班级电信091 姓名学号成绩教师签名实验目的:1、了解FTP服务的体系结构与工作原理2、掌握利用Microsoft的IIS实现FTP服务的基本配置3、熟悉常见的FTP命令的使用实验原理:1、文件传输协议(FTP)是用于在网络上进行文件传输的一套标准协议,它属于网络协议的应用层。
FTP的主要功能是在主机间高速可靠的传输文件。
2、FTP服务一般运行在20、21两个端口,端口20用于在客户端和服务器之间进行传输数据流,而端口21用于传输控制流,并且是命令通向ftp服务器的进口。
当数据通过数据流传输时,控制流处于空闲状态。
当控制流空闲很长时间后,客户端的防火墙会把其会话置为超时,这样当大量的数据通过防火墙时,会产生一些问题。
此时,虽然文件可以成功的传输,但因为控制会话会被防火墙断开,传输会产生一些错误。
FTP实现的目标:1)促进文件的共享(包括计算机程序或者数据)2)鼓励间接的使用远程计算机3)向用户屏蔽不同主机中各种文件存储系统的细节4)可靠和高效的传输数据3、FTP命令:.ascii:使用ascii类型传输方式。
.bell:每个命令执行完毕后计算机响铃一次。
.bin:使用二进制文件传输方式。
.bye:退出ftp会话过程。
.case:在使用mget时,将远程主机文件名中的大写转为小写字母。
.cd remote-dir:进入远程主机目录。
.cdup:进入远程主机目录的父目录。
.chmod mode file-name:将远程主机文件file-name的存取方式设置为mode,如:chmod 777 a.out。
.close:中断与远程服务器的ftp会话(与open对应)。
.cr:使用asscii方式传输文件时,将回车换行转换为回行。
昆明理工大学(计算机网络)实验报告实验名称文件传输协议FTP服务配置实验实验时间2012年5月专业班级电信091 姓名学号成绩教师签名实验目的:1、了解FTP服务的体系结构与工作原理2、掌握利用Microsoft的IIS实现FTP服务的基本配置3、熟悉常见的FTP命令的使用实验原理:1、文件传输协议(FTP是用于在网络上进行文件传输的一套标准协议,它属于网络协议的应用层。
FTP的主要功能是在主机间高速可靠的传输文件。
2、FTP服务一般运行在20、21两个端口,端口20用于在客户端和服务器之间进行传输数据流,而端口21用于传输控制流,并且是命令通向ftp服务器的进口。
当数据通过数据流传输时,控制流处于空闲状态。
当控制流空闲很长时间后,客户端的防火墙会把其会话置为超时,这样当大量的数据通过防火墙时, 会产生一些问题。
此时,虽然文件可以成功的传输,但因为控制会话会被防火墙断开,传输会产生一些错误。
FTP实现的目标:1) 促进文件的共享(包括计算机程序或者数据)2) 鼓励间接的使用远程计算3)向用户屏蔽不同主机中各种文件存储系统的细节4)可靠和高效的传输数据3、FTP命令:・ ascii :使用ascii 类型传输方式。
• bell :每个命令执行完毕后计算机响铃一次。
•bin :使用二进制文件传输方式。
•bye :退岀ftp 会话过程。
.case :在使用mget时,将远程主机文件名中的大写转为小写字母。
•cd remote-dir :进入远程主机目录。
•cdup :进入远程主机目录的父目录。
的存取方式设置为mode 女口: chmod 777 a. out o■ chmod mode file-name :将远程主机文件file -name.close :中断与远程服务器的ftp会话(与open对应)。
• or :使用asscii方式传输文件时,将回车换行转换为回行。
.delete remote-file :删除远程主机文件。
ftp实验报告一、实验目的1.在linux系统上完成一个FTP协议的简单实现。
2.深入了解FTP的原理和协议细节。
3.学会利用socket接口设计简单的应用层协议,掌握TCP/IP网络应用程序的基本设计方法和实现技巧。
二、实验内容实现以下FTP命令1.get:取远方的一个文件。
2.put:传给远方一个文件。
3.pwd:显示远方的当前目录。
4.dir:列出远方的当前目录。
5.cd:改变远方的当前目录。
6.?:显示提供的命令。
7.quit:退出。
三、思考题1.为什么需要建立两个TCP连接来分别传输命令和数据?为了在传输数据的同时还能进行控制。
2.主动方式和被动方式的区别是什么,为什么要设计这两种不同的方式?主动方式:客户端开好数据端口,服务器通过20端口向客户端数据端口发送连接请求被动方式:服务器开好数据端口并通过命令端口来告知客户端,等待客户端连接PASV模式出现的目的之一是防止客户端防火墙的影响。
3.当使用FTP下载大量小文件的时候,速度会很慢,为什么,怎么改进?因为每一个文件的传输都要在控制连接中发送几次控制命令并且每次都要重新关闭和打开数据连接,因此速度很慢。
可以通过保留每一次的数据连接以减少时间消耗。
四、源代码及注释见附件。
五、源代码(linux下)server.cpp#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fstream>#include <dirent.h>#include <sys/socket.h>#include <sys/types.h>#include <signal.h>#include <arpa/inet.h>#include <pthread.h>#include <assert.h>#include <string>#include <netinet/in.h>#include <iostream>#define BUF_SIZE 256#define ROOT_DIR "."using namespace std;enum DataType {TYPE_ASCII, TYPE_IMAGE};//打印线程信息void log(const string & s){pthread_t th = pthread_self();printf("[PID %d] %s \n", th, s.c_str());}//根据文件名,将文件读到content中去int readFile(const string & filename, string & content){ log("Reading file: " + filename);ifstream in(ROOT_DIR + filename, ios::in | ios::binary);if(in){content = "";in.seekg(0, ios::end);//获得文件大小content.resize(in.tellg());in.seekg(0, ios::beg);//复制文件in.read(&content[0], content.size());in.close();log("Read file ok. Size: " + to_string(content.size()));return 0;}log("Read file error.");return -1;}//将content中的内容存到文件名为filename的文件中int storeFile(const string & filename, string & content){ log("Writing to file: " + filename);ofstream out(ROOT_DIR + filename, ios::out | ios::binary);if(out){out << content;out.close();log("Write ok. Size: " + to_string(content.size()));return 0;}log("Write file error.");return -1;}//列出cwd下的文件列表int listDir(string cwd, string & ret){ret = "";DIR * dp;struct dirent *ep;dp = opendir((ROOT_DIR + cwd).c_str());if(dp == NULL) return -1;while(ep = readdir(dp)){ret += ep->d_name;ret += "\r\n";}closedir(dp);return 0;}//读控制连接string readCmd(int sockfd, bool logging = true){string buf;char _tmp[BUF_SIZE];while(true){int _len = read(sockfd, _tmp, BUF_SIZE - 1);for(int i = 0 ; i < _len ; i += 1) buf += _tmp[i];if(_len == 0 || _tmp[_len-1] == '\n') break;}while(buf.length() != 0 && (buf.back() == '\n' || buf.back() == '\r')) buf.pop_back();if(logging){string to_print = "Recv: " + buf +"[len:" + to_string(buf.length()) + "]";log(to_print);}return buf;}//写控制连接int writeCmd(int sockfd, int code, const string & msg){string buf = to_string(code);buf += ' ';buf += msg;log("Send: " + buf);buf += "\r\n";return write(sockfd, buf.c_str(), buf.length());}//启动被动模式,开启数据连接int openPasvSocket(int sockfd){struct sockaddr_in localaddr, dataserv_addr, datacli_addr;socklen_t localaddrlen = sizeof(localaddr),datacli_addr_len = sizeof(datacli_addr),dataserv_addr_len = sizeof(datacli_addr);//得到客户端的地址getsockname(sockfd, (struct sockaddr*)&localaddr, &localaddrlen);//换成点分十进制的地址string ret_str = inet_ntoa(localaddr.sin_addr);for(int i = 0 ; i < ret_str.length() ; i += 1)if(ret_str[i] == '.') ret_str[i] = ',';//配置数据连接的地址dataserv_addr.sin_family = AF_INET;dataserv_addr.sin_addr.s_addr = INADDR_ANY;dataserv_addr.sin_port = 0;int dataserve_sock = socket(AF_INET, SOCK_STREAM, 0);//绑定if(bind(dataserve_sock, (struct sockaddr *)&dataserv_addr,sizeof(dataserv_addr)) < 0){log("Bind PASV socket error.");writeCmd(sockfd, 421, "Service not available");return -1;}//监听listen(dataserve_sock, 1);//获取本地的数据端口getsockname(dataserve_sock, (struct sockaddr *)&dataserv_addr, &datacli_addr_len);unsigned int dataserv_port = ntohs(dataserv_addr.sin_port);log((string("PASV socket port: ") +to_string(dataserv_port)).c_str());ret_str += ",";ret_str += to_string(dataserv_port >> 8) + ",";ret_str += to_string(dataserv_port & 0xff) + ").";ret_str = "Entering Passive Mode (" + ret_str;//通过控制连接将数据端口发送给客户端writeCmd(sockfd, 227, ret_str);log("Listening PASV socket.");//等待客户端连接数据端口int newfd = accept(dataserve_sock,(struct sockaddr *)&datacli_addr,(socklen_t *)&datacli_addr_len);log("PASV socket accepted.");close(dataserve_sock);return newfd;}//写数据连接void writeData(int sockfd, int &datasock,const void * buf, int buf_len){if(datasock < 0){writeCmd(sockfd, 150, "File status okay. About to open data connection.");return ;}writeCmd(sockfd, 125, "Data connection already open. Transfer starting.");write(datasock, buf, buf_len);close(datasock);datasock = -1;writeCmd(sockfd, 226, "Transfer complete.");}//读数据连接void readData(int sockfd, int &datasock, string & content){content = "";if(datasock < 0){writeCmd(sockfd, 150, "File status okay. About to open data connection.");return ;}writeCmd(sockfd, 125, "Data connection already open. Transfer starting.");char _tmp[BUF_SIZE];while(1){int _len = read(datasock, _tmp, BUF_SIZE-1);for(int i = 0 ; i < _len ; i += 1) content += _tmp[i];if(_len <= 0) break;}close(datasock);datasock = -1;writeCmd(sockfd, 226, "Transfer complete.");}void * workThread(void * clientcmdID){//工作线程signal(SIGPIPE, SIG_IGN);int clientcmdsock = *(int *)clientcmdID;//clientcmdsockstring buf;//当前相对路径string cwd = "/";int datasock = -1;//220 对新用户准备完毕writeCmd(clientcmdsock, 220, "preperation done, ftp is available");while(true){//取命令buf = readCmd(clientcmdsock);if(buf.length() == 0){log("Read error. exit.");break;}char * buf_str = new char[buf.length() + 1];strcpy(buf_str, buf.c_str());// 取命令的前部,转成C风格字符串char * CMDCode = strtok(buf_str, " \r\n");if(strcmp(CMDCode, "QUIT") == 0) break;if(strcmp(CMDCode, "PASV") == 0){//启动被动模式,准备数据连接datasock = openPasvSocket(clientcmdsock);continue;}if(strcmp(CMDCode, "PWD") == 0){string _tmp = '"' + cwd + '"';//使用命令连接传送当前路径writeCmd(clientcmdsock, 257, _tmp + " is the current path.");continue;}if(strcmp(CMDCode, "DIR") == 0){string _tmp;//列出当前路径下的文件名listDir(cwd, _tmp);//使用数据连接发送当前文件夹下的文件列表writeData(clientcmdsock, datasock, _tmp.c_str(), _tmp.length());continue;}if(strcmp(CMDCode, "CD") == 0){//改变路径//取第二个参数路径转移目标CMDCode = strtok(NULL, " \r\n");string _tmp;if(listDir(cwd+CMDCode, _tmp) == 0){cwd += CMDCode;cwd += '/';writeCmd(clientcmdsock, 200, "Changed dir to " + cwd + ".");}else writeCmd(clientcmdsock, 550, "Dir not exist.");continue;}if(strcmp(CMDCode, "GET") == 0){//下载文件CMDCode = strtok(NULL, " \r\n");string _tmp;if(readFile(cwd+CMDCode, _tmp) == 0)//使用数据连接发送文件流writeData(clientcmdsock, datasock, _tmp.c_str(), _tmp.length());else writeCmd(clientcmdsock, 550, "Open file error.");continue;}if(strcmp(CMDCode, "PUT") == 0){CMDCode = strtok(NULL, " \r\n");string _tmp;//使用数据连接接收文件流readData(clientcmdsock, datasock, _tmp);storeFile(cwd+CMDCode, _tmp);continue;}// other commandwriteCmd(clientcmdsock, 500, "Unknown command.");}close(clientcmdsock);close(datasock);log("Quiting...");return NULL;}int main(int argc, char ** argv){//第一个参数是端口//检查参数个数if(argc < 2){cout << "usage:sudo ./server port" << endl;return -1;}int cmdsock = socket(AF_INET, SOCK_STREAM, 0);//检查是否socket是否创建成功if(cmdsock < 0){cout << "create socket failed" << endl;return -1;}struct sockaddr_in serv_addr, cli_addr;//配置本地地址信息serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = INADDR_ANY;serv_addr.sin_port = htons(atoi(argv[1]));//绑定地址int ret = bind(cmdsock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));if(ret < 0){cout << "bind failed" << endl;return -1;}//开始监听ret = listen(cmdsock, 5);if(ret < 0){cout << "listen failed" << endl;return -1;}pthread_t thread;puts("Listening...");while(true){int cli_addr_len = sizeof(cli_addr);//接收客户端的连接请求int clientcmdsock = accept(cmdsock, (struct sockaddr *)&cli_addr, (socklen_t *)&cli_addr_len);//创建线程处理与客户端的通信pthread_create(&thread, NULL, workThread, (void *)&clientcmdsock);cout << "accept a new connection from" << inet_ntoa(cli_addr.sin_addr)<< ":" << ntohs(cli_addr.sin_port) << ", thread:" << thread << endl;}return 0;}client.cpp#include <stdio.h>#include <stdlib.h>#include <iostream>#include <string.h>#include <unistd.h>#include <fstream>#include <dirent.h>#include <sys/socket.h>#include <sys/types.h>#include <signal.h>#include <arpa/inet.h>#include <assert.h>#include <string>#include <netinet/in.h>#include <netdb.h>#define BUF_SIZE 256#define ROOT_DIR "."using namespace std;//根据文件名,将文件读到content中去int readFile(const string & filename, string & content){ printf("Reading file: %s\n", filename.c_str());ifstream in(filename, ios::in | ios::binary);if(in){content = "";in.seekg(0, ios::end);//获得文件大小content.resize(in.tellg());in.seekg(0, ios::beg);//复制文件in.read(&content[0], content.size());in.close();printf("Read ok\n");return 0;}printf("Read error.\n");return -1;}//将content中的内容存到文件名为filename的文件中int storeFile(const string & filename, string & content){ printf("Writing file: %s\n", filename.c_str());ofstream out(filename, ios::out | ios::binary);if(out){out << content;out.close();printf("Write ok. ");return 0;}printf("Write file error.");return -1;}//读控制连接string readCmd(int sockfd){string buf;char _tmp[BUF_SIZE];while(1){int _len = read(sockfd, _tmp, BUF_SIZE - 1);for(int i = 0 ; i < _len ; i += 1) buf += _tmp[i];if(_len == 0 || _tmp[_len-1] == '\n') break;}while(buf.length() != 0 && (buf.back() == '\n' || buf.back() == '\r')) buf.pop_back();return buf;}//写控制连接string sendCmd(int cmdsock, string msg){//sockfd 服务器msg += "\r\n";write(cmdsock, msg.c_str(), msg.length());string ret = readCmd(cmdsock);cout << ret << endl;return ret;}int connectSocket(const char * host, int port){//连接到服务器printf("Connecting to %s:%d\n", host, port);int sockfd = -1;struct sockaddr_in serv_addr;struct hostent *server;//创建一个socketsockfd = socket(AF_INET, SOCK_STREAM, 0);//含有服务器的相关信息server = gethostbyname(host);if(server == NULL){printf("No such host.\n");return -1;}serv_addr.sin_family = AF_INET;//拷贝地址信息memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);//设置连接的端口serv_addr.sin_port = htons(port);//建立连接if(connect(sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0){ printf("Connect error.\n");return -1;}printf("Connect OK.\n");//返回连接的socketreturn sockfd;}int connectPASV(int cmdsock){//sockfd 服务器printf("Connecting PASV...\n");string tmp("PASV");//发送请求被动连接命令tmp = sendCmd(cmdsock, tmp);//检查返回值,返回值包含了数据连接的地址和端口assert(strncmp(tmp.c_str(), "227", 3) == 0);tmp = tmp.substr(tmp.find('(') + 1);string _addr;//获取数据连接的地址for(int i = 0, dot_count=0; i < tmp.length() ; i += 1){ if(tmp[i] == ','){if(dot_count == 3) break;tmp[i] = '.';dot_count += 1;}_addr += tmp[i];}//获取数据连接的端口unsigned int port = 0;tmp = tmp.substr(tmp.find(',') + 1);char * s = new char[tmp.length() + 1];strcpy(s, tmp.c_str());port = atoi(strtok(s, ",) "));port <<= 8;port += atoi(strtok(NULL, ",) "));delete []s;//创建并返回数据连接return connectSocket(_addr.c_str(), port);}//写数据连接void readData(int &datasock, string & content){content = "";char _tmp[BUF_SIZE];while(1){int _len = read(datasock, _tmp, BUF_SIZE-1);for(int i = 0 ; i < _len ; i += 1) content += _tmp[i];if(_len <= 0) break;}//close(datasock);//datasock = -1;}void printHelp(){cout << "GET:取回服务器一个文件" << endl<< "PUT:传给服务器一个文件" << endl<< "PWD:显示服务器当前目录" << endl<< "DIR:显示服务器当前目录下的文件" << endl<< "CD:改变服务器目录" << endl<< "?:帮助" << endl;}int main ( int argc, char *argv[] ){assert(argc > 1);signal(SIGPIPE, SIG_IGN);//控制连接,连接服务器int cmdsock = connectSocket(argv[1], 21);assert(cmdsock >= 0);string tmp = readCmd(cmdsock);cout << tmp << endl;int datasock = -1;while(true){//数据连接if(datasock < 0) datasock = connectPASV(cmdsock);string cmd;printf("> ");//获取命令getline(cin, cmd);while(cmd.back() == '\n' || cmd.back() == '\r' || cmd.back() == ' ') cmd.pop_back();if(strncmp("?", cmd.c_str(), 1) == 0){printHelp();continue;}//通过控制连接发送命令string reply = sendCmd(cmdsock, cmd);if(strncmp("125", reply.c_str(), 3) == 0){//如果发送控制指令成功string filecontent;//只有存、取和列在本地才会有后续操作//存文件if(strncmp("PUT", cmd.c_str(), 3) == 0){//取文件名tmp = cmd.substr(cmd.find(' ') + 1);//读本地文件assert(readFile(tmp, filecontent) >= 0);//写数据连接write(datasock, filecontent.c_str(), filecontent.size());//关闭数据连接close(datasock);}//下载文件if(strncmp("GET", cmd.c_str(), 3) == 0){//取文件名tmp = cmd.substr(cmd.find(' ') + 1);//读数据连接readData(datasock, filecontent);//写本地文件assert(storeFile(tmp, filecontent) >= 0);//关闭数据连接close(datasock);}if(strncmp("DIR", cmd.c_str(), 3) == 0){readData(datasock, filecontent);cout << filecontent << endl;//关闭数据连接close(datasock);}if(strncmp("PWD", cmd.c_str(), 3) == 0)cout << reply << endl;elsedatasock = -1;//再读一行命令连接??readCmd(cmdsock);}}return EXIT_SUCCESS;}。
FTP协议实验报告●实验目的1、在Linux系统上完成一个文件传输协议(FTP)的简单实现。
2、深入理解FTP协议的原理和协议细节。
3、学会利用Socket接口设计实现简单应用层协议。
4、掌握TCP/IP网络应用程序的基本设计方法和实现技巧。
●实验原理1、FTP协议FTP是File Transfer Protocol,即文件传输协议的缩写。
该协议用于在两台计算机之间传送文件。
FTP会话包括了两个通道,一个是控制通道,一个是数据通道。
控制通道是和FTP 服务器进行沟通的通道,连接FTP服务器,发送FTP指令;数据通道则是和FTP服务器进行文件传输或者获取文件列表的通道。
FTP协议中,控制连接的各种指令均由客户端主动发起,而数据连接有两种工作方式:主动方式(PORT方式)和被动方式(PASV方式)。
主动方式下,FTP客户端首先和FTP服务器的控制通道对应端口(一般为21)建立连接,通过控制通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。
PORT命令包含了客户端用什么端口(一个大于1024的端口)接收数据。
在传输数据的时候,FTP服务器必须和客户端建立一个新的连接,服务器通过自己的TCP 20端口发送数据。
被动方式下,建立控制通道的过程和主动方式类似,当客户端通过这个通道发送PASV命令的时候,FTP server打开一个位于1024-5000之间的随机端口并且通知客户端,然后客户端与服务器之间将通过这个端口进行数据的传送。
2、socket编程(1)什么是SocketSocket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程。
网络的Socket 数据传输是一种特殊的I/O,Socket也是一种文件描述符。
(2)Socket的建立为了建立Socket,程序可以调用Socket函数,该函数返回一个socket描述符。
Socket 描述符是一个指向内部数据结构的指针,它指向描述符表入口。
ftp协议实验报告FTP协议实验报告引言:FTP(File Transfer Protocol)是一种用于在计算机网络上进行文件传输的标准协议。
它提供了简单可靠的文件传输功能,被广泛应用于互联网和局域网中。
本实验旨在通过实际操作和分析,深入了解FTP协议的工作原理和特点。
一、实验目的本实验的主要目的是通过搭建FTP服务器和客户端,进行文件的上传和下载操作,以及对FTP协议进行分析和评估。
具体目标如下:1. 理解FTP协议的基本原理和工作机制;2. 掌握FTP服务器和客户端的搭建方法;3. 进行文件上传和下载操作,并分析传输性能;4. 分析FTP协议的优缺点,评估其适用性和安全性。
二、实验环境1. 操作系统:Windows 10;2. 软件工具:FileZilla Server、FileZilla Client;3. 硬件设备:一台可联网的计算机。
三、实验步骤1. 安装和配置FTP服务器:首先,下载并安装FileZilla Server软件。
然后,根据软件提供的向导,进行服务器的配置和设置。
包括设置监听端口、创建用户账户、指定共享文件夹等。
2. 启动FTP服务器:在配置完成后,启动FileZilla Server软件,使其开始监听指定的端口,并等待客户端的连接请求。
3. 安装和配置FTP客户端:下载并安装FileZilla Client软件。
然后,打开软件并进行配置。
配置内容包括指定FTP服务器的地址和端口、输入用户账户和密码等。
4. 连接FTP服务器:在客户端软件中,点击“连接”按钮,与FTP服务器建立连接。
如果配置正确,连接将会成功建立。
5. 进行文件上传和下载操作:在连接成功后,可以在客户端的界面中看到本地文件和服务器文件的目录结构。
通过简单的拖拽操作,可以实现文件的上传和下载。
四、实验结果分析1. 文件传输性能:通过实验可以发现,FTP协议在文件传输方面具有较高的性能。
在局域网内,文件的上传和下载速度都很快,可以满足一般用户的需求。
《网络协议》实验报告实验名称:文件传输协议(FTP)组别机器号:第六组主机B班级:网络13-3班学号:1320020306姓名:黄腾飞指导教师:陈虹成绩:一、实验目的1. 掌握FTP的工作原理2. 掌握FTP一些常用命令的使用方法及用途二、实验环境实验拓扑结构(标注IP地址和MAC地址):IP地址:172.16.0.62 MAC地址:002511-53EB30三、实验内容FTP的工作过程。
四、实验过程及结果分析FTP的工作过程本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。
现仅以主机A、B所在组为例,其它组的操作参考主机A、B所在组的操作。
1. 主机B启动协议分析器进行数据捕获并设置过滤条件(提取FTP data和FTP control协议)。
2. 主机A登录FTP服务器:在实验环境中的FTP服务器(172.16.1.100)已经启动,并提供一个公共帐号,用户名是:anonymous,口令:无。
在命令行提示符下运行:(1)C:\>ftp 172.16.1.100(2)在“User:”提示符后输入用户名:anonymous(3)在“Password:”提示符后输入密码:无(4)在客户端上运行一个简单的操作,如:ftp> dir(5)在FTP提示符下输入“quit”退出FTP3. 察看主机B捕获的数据,保存会话命令(方法:会话交互视图/单击右键/保存会话命令菜单,保存为FTP.txt),并分析FTP的工作过程:●FTP使用的TCP端口有哪些___20\ 21______。
●分析FTP报文格式。
指出在捕获数据报文中含有用户名、密码的报文,是否可以看到用户名和密码?说明FTP的安全性?可以看到用户名和密码,安全性低。
使用TCP连接工具与服务器进行命令交互本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。
现仅以主机A、B所在组为例,其它组的操作参考主机A、B所在组的操作。
组号: 3F 学号:53131016 姓名:杨灵实验7.1 FTP协议【实验目的】学习FTP协议的连接过程;理解FTP协议的工作原理.一人一组,一组提交报告。
【实验环境】本实验采用网络结构一,一定要设置DNS服务器,地址是:172.16.0.253 主机的IP地址使用172.16。
0.0段。
掩码255.255。
255.0.IP地址分配方法:172.16。
0。
组号、主机号例如:第2组的B主机的IP地址设置为172.16.0。
22第5组的F主机的IP地址设置为 172。
16。
0.56【实验内容】本实验要求:FTP服务器已经启动,并提供一个公共帐户,用户名是:anonymous,口令:无。
或用户名:group2_1,口令:group2_1 (可以上传数据)。
练习一 FTP本实验学生独立完成,目的是了解FTP协议的端口和连接过程。
实验步骤:1、主机启动协议分析器,打开数据捕获窗口,设置过滤条件(提取FTP协议);2、主机登录FTP服务器:在仿真端的命令行提示符下运行:>ftp 172。
16。
0.253LOGIN:〉group2_1PASS:〉group2_1〉dir>quit3、查看主机捕获的数据,在会话分析中,查看TCP会话中的21端口和20端口的会话情况,记录21端口和20端口的会话过程;●记录实验结果:①粘贴捕获包的截图;②是否可以捕获到用户名和密码?答:可以,在USER和PASS会话中。
③21端口和20端口分别传输什么内容?答:一个是数据端口,一个是控制端口,控制端口一般为21,而数据端口不一定是20,这和FTP的应用模式有关,如果是主动模式,应该为20,如果为被动模式,由服务器端和客户端协商而定。
练习二使用浏览器登入FTP1、主机启动协议分析器,打开数据捕获窗口;2、主机启动IE浏览器,在“地址”框中输入ftp://172.16。
0.2533、查看主机捕获的数据,在会话分析中,查看TCP会话中的端口情况。
实验九 FTP 文件传输协议FTP 服务器地址为202.117.144.29,202.117.144.29,用户名为用户名为anonymous,anonymous,密码为密码为空一 实验目的1、 理解理解理解 FTP FTP FTP 协议的工作原理;协议的工作原理;协议的工作原理;2、 了解了解了解 FTP FTP FTP 协议的常用命令;协议的常用命令;协议的常用命令;3、 了解应用层协议与传输层协议的关系了解应用层协议与传输层协议的关系。
二 实验内容1、 学习学习学习 FTP FTP FTP 协议的工作原理;协议的工作原理;协议的工作原理;2、 学习学习学习 FTP FTP FTP 的使用方法;的使用方法;的使用方法;3、 了解了解了解 FTP FTP FTP 的常用命令;的常用命令;的常用命令;4、 了解了解了解 FTP FTP FTP 的工作过程;的工作过程;的工作过程;5、 理解理解理解 FTP FTP FTP 的主动模式和被动模式。
的主动模式和被动模式。
的主动模式和被动模式。
三 实验环境四 实验流程五 实验原理FTP(File Transfer Protocol)FTP(File Transfer Protocol),是文件传输协议的简称。
用,是文件传输协议的简称。
用于 Internet Internet 上的控制文件的双向传输。
上的控制文件的双向传输。
同时,它也是一个应用程序(Application)(Application)。
用户可以通过它把自己的。
用户可以通过它把自己的。
用户可以通过它把自己的 PC PC PC 机与世界各地所有运机与世界各地所有运行 FTP 协议的服务器相连,访问服务器上的大量程序和信息。
协议的服务器相连,访问服务器上的大量程序和信息。
1、 FTP FTP 工作原理工作原理工作原理拿下传文件为例,当你启动拿下传文件为例,当你启动拿下传文件为例,当你启动 FTP FTP FTP 从远程计算机拷贝文件时,你从远程计算机拷贝文件时,你事实上启动了两个程序:一个本地机上的事实上启动了两个程序:一个本地机上的 FTP FTP FTP 客户程序:它向客户程序:它向客户程序:它向 FTP FTP 服务器提出拷贝文件的请求。
1. 实验报告如有雷同,雷同各方当次实验成绩均以0分计。
在规定时间内未上交实验报告的,不得以其他方式补交,当次成绩按0分计。
3.实验报告文件以PDF 格式提交。
实验1 FTP 协议分析实验【实验目的】分析FTP 协议的安全性。
【实验步骤】1.下载并安装Serv-U 。
2. 配置FTP 服务器;建立用户名和密码(例如用户名是USER ,密码PASS );选择否,在用户配置中设置。
选择域详细信息:域根目录设置成FTP的目录并保存。
返回控制台主页并选择用户:添加用户:添加成功:3.使用协议分析软件wireshark,设置好过滤规则为ftp;安装软件:设置过滤规则为ftp:192.168.22.504.客户端使用ftp命令访问服务器端,输入用户名和密码;客户端在地址栏输入主机IP地址:登录界面,表示ftp建立成功:5. 开始抓包,从捕获的数据包中分析用户名/口令;抓包所得文件在附件中给出(packet.cap)。
由以上语句可以分析出用户名和口令分别为USER和PASS。
6. 讨论FTP协议的安全问题。
对于本实验来说,由于客户端的单一性,只设置一个帐号和密码就可以满足要求,但是当用户数量增多而且要求各客户端数据保密的话,安全性的问题就凸显出来了,具体的解决办法如下所示:假设有多个用户:选择用户属性,选中“用户必须在下一次登陆时更改密码”(确保安全性):进入控制台“限制和设置”设置“允许用户更改密码”选择“是”保存在地址栏输入ftp地址192.168.22.50,到达登陆界面输入原始帐号密码(USER/PASS),出现更改密码的对话框:确定之后登录,密码得以更改,之后步骤类似与一个用户情况。
7.设置Serv-U的安全连接功能,重复步骤2-4,看是否能保证用户名/口令的安全?安全连接功能的设置见第6个步骤。
【实验工具】使用Wireshark可以很方便地对截获的数据包进行分析,包括该数据包的源地址、目的地址、所属协议等。
FTP协议分析报告
实验目的
通过实验了解FTP协议是怎么运行的
实验原理
通过虚拟机访问构建在主机上的FTP服务器,利用Wireshark抓包分析FTP协议实验步骤
在主机上构建FTP服务器
打开软件,配置好信息
打开Wireshark抓包工具,找到合适网卡,选择过滤关键字
从虚拟机访问FTP服务器
先要知道主机服务器的IP地址,可以通过ipconfig密令知道
打开虚拟机的密令界面
开始进入FTP服务器
输入用户名密码
用LS查看ftp目录下的文件
用CD密令进入子目录查看文件
从FTP服务器上下载文件
查看抓到的包并简要分析
验证FTP是否是明文传输。
FTP协议实验报告●实验目的1、在Linux系统上完成一个文件传输协议(FTP)的简单实现。
2、深入理解FTP协议的原理和协议细节。
3、学会利用Socket接口设计实现简单应用层协议。
4、掌握TCP/IP网络应用程序的基本设计方法和实现技巧。
●实验原理1、FTP协议FTP是File Transfer Protocol,即文件传输协议的缩写。
该协议用于在两台计算机之间传送文件。
FTP会话包括了两个通道,一个是控制通道,一个是数据通道。
控制通道是和FTP 服务器进行沟通的通道,连接FTP服务器,发送FTP指令;数据通道则是和FTP服务器进行文件传输或者获取文件列表的通道。
FTP协议中,控制连接的各种指令均由客户端主动发起,而数据连接有两种工作方式:主动方式(PORT方式)和被动方式(PASV方式)。
主动方式下,FTP客户端首先和FTP服务器的控制通道对应端口(一般为21)建立连接,通过控制通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。
PORT命令包含了客户端用什么端口(一个大于1024的端口)接收数据。
在传输数据的时候,FTP服务器必须和客户端建立一个新的连接,服务器通过自己的TCP 20端口发送数据。
被动方式下,建立控制通道的过程和主动方式类似,当客户端通过这个通道发送PASV命令的时候,FTP server打开一个位于1024-5000之间的随机端口并且通知客户端,然后客户端与服务器之间将通过这个端口进行数据的传送。
2、socket编程(1)什么是SocketSocket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程。
网络的Socket 数据传输是一种特殊的I/O,Socket也是一种文件描述符。
(2)Socket的建立为了建立Socket,程序可以调用Socket函数,该函数返回一个socket描述符。
Socket 描述符是一个指向内部数据结构的指针,它指向描述符表入口。
调用Socket函数时,socket 执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。
Socket执行体为你管理描述符表。
两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。
Socket数据结构中包含这五种信息。
socket函数原型为:int socket(int domain, int type, int protocol);domain:指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type:指定socket的类型为SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket (SOCK_RAW),允许程序使用低层协议;protocol:通常赋值"0"。
返回:整型socket描述符。
(3)Socket配置无连接socket的客户端和服务端以及面向连接socket的服务端通过调用bind函数来配置本地信息。
Bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。
Bind函数原型为:int bind(int sockfd,struct sockaddr_in *my_addr, int addrlen);Sockfd:调用socket函数返回的socket描述符my_addr:一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针addrlen:常被设置为sizeof(struct sockaddr)。
struct sockaddr_in结构类型是用来保存socket信息的:struct sockaddr_in {short int sin_family; /* 地址族*/unsigned short int sin_port; /* 端口号*/struct in_addr sin_addr; /* IP地址*/unsigned char sin_zero[8]; /* 填充0 以保持与struct sockaddr同样大小*/};sin_zero:用来将sockaddr_in结构填充到与struct sockaddr同样的长度,可以用bzero()或memset()函数将其置为零。
使用bind函数时,可以用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号:my_addr.sin_port = 0; /* 系统随机选择一个未被使用的端口号*/my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本机IP地址*/通过将my_addr.sin_port置为0,函数会自动为你选择一个未占用的端口来使用。
同样,通过将my_addr.sin_addr.s_addr置为INADDR_ANY,系统会自动填入本机IP地址。
Bind()函数在成功被调用时返回0;出现错误时返回"-1"并将errno置为相应的错误号。
需要注意的是,在调用bind函数时一般不要将端口号置为小于1024的值,因为1到1024是保留端口号,你可以选择大于1024中的任何一个没有被占用的端口号。
(4)连接建立无连接协议从不建立直接连接。
面向连接的服务器也从不启动一个连接,它只是被动的在协议端口监听客户的请求。
Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。
int listen(int sockfd,int backlog);Sockfd:Socket系统调用返回的socket 描述符backlog:指定在请求队列中允许的最大请求数,进入的连接请求将在队列中等待accept()。
如果一个服务请求到来时,输入队列已满,该socket将拒绝连接请求,客户将收到一个出错信息。
返回:当出现错误时listen函数返回-1,并置相应的errno错误码。
accept()函数让服务器接收客户的连接请求。
在建立好输入队列后,服务器就调用accept 函数,然后睡眠并等待客户的连接请求。
int accept(int sockfd, void *addr, int *addrlen);sockfd:被监听的socket描述符;addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求);addrten:通常为一个指向值为sizeof(struct sockaddr_in)的整型指针变量;返回:出现错误时accept函数返回-1并置相应的errno值。
(5)结束传输当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:close(sockfd);●实验内容在Linux系统上使用Socket接口实现FTP客户端和服务器的程序,使客户端可以连接至服务器,并且可以进行一些FTP的基本操作,如列出目录、下载文件等。
从FTP协议的实现角度来看,客户端与服务器的命令通道和数据通道需要分享,同时应该支持以下一些FTP 命令:get:取远方的一个文件。
put:传给远方一个文件。
pwd:显示远方当前目录。
dir:列出远方当前目录。
cd:改变远方当前目录。
:显示你提供的命令quit:退出返回●实验过程1、实现服务器端(1)全局变量(2)函数在服务器端实现了以下几个函数:先建立数据通道和命令通道,然后监听,若有客户端连上,则建立一个子进程,先向客户端发送帮助信息,然后根据客户端的命令来调用上述各函数来处理。
由当前工作目录的绝对地址得到当前工作目录的名称,当前工作目录的名称是绝对地址中最后一个“/”号之后的字符串,通过从后向前遍历绝对地址字符串找到最后一个“/”,然后再取其后的字符串即可得到当前工作目录的名称。
调用getDirName函数来得到当前工作目录名称,然后发到客户端(6)void cmd_dir(int sock)的实现:先遍历当前目录下的所有文件及子目录,得到文件及目录数,把该数目发给客户端后,再一次遍历当前目录下的所有文件及子目录,把文件或目录的名称及信息发给客户端。
(7) void cmd_cd(int sock,char *dirName)的实现:遍历当前目录查看是否有与客户输入的目录名相同的目录,这里要区分普通目录和上一级目录(即..),若为普通目录则直接在存放当前目录绝对地址的字符串的后面加上新进的目录,若为上一级目录,则要在存放当前目录绝对地址的字符串中删去最后一个目录,即最(8)void cmd_help(int sock)的实现:把存有帮助信息的字符串发到客户端(9)void cmd_get(int sock,char*fileName)的实现:把文件内容一部分一部分地读到缓冲区,然后发给客户端(10)void cmd_put(int sock,char *fileName)的实现:从客户端一部分一部分地读文件到续冲区,然后写入文件。
先与服务器端建立连接,然后处理向服务客端发送的各种命令。
(4)void cmd_pwd(int sock,int sockmsg)的实现:(5)void cmd_dir(int sock,int sockmsg)的实现:向服务器发出dir命令,然后接收服务器发来的文件及目录数目,打印出来,接着依次接收服务器发来的文件或目录信息,打印出来。
(6)void cmd_cd(int sock,int sockmsg,char *dirName)的实现:(8)void cmd_get(int sock,int sockmsg,char *fileName)的实现:把get命令和文件名发到服务器,然后一部分一部分地接收服务器发来的字节流,缓存到缓冲区,然后写到本地文件中。
(9)void cmd_put(int sock,int sockmsg,char *fileName)的实现:与cmd_get命令类似,先向服务器发出put命令和文件名,然后把文件一部分一部分地读到缓冲区,然后再发送到服务器。
(10)void cmd_quit(int sock,int sockmsg)的实现:向服务器发出quit命令。
实验总结1、遇到的困难及解决方法(1)服务器的socket总是bind不成功,总是显示address already in use产生原因及解决方法是在网上找到的。
原因为先前的socket还处于连接状态,占用原有端口,可以通过setsockopt函数主动清除这种连接。