linux C FTP 实验报告.docx
- 文档编号:2701707
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:24
- 大小:341.17KB
linux C FTP 实验报告.docx
《linux C FTP 实验报告.docx》由会员分享,可在线阅读,更多相关《linux C FTP 实验报告.docx(24页珍藏版)》请在冰点文库上搜索。
linuxCFTP实验报告
计算机学院实验报告
课程 《LINUX系统》
实验名称 FTPSERVER&CLIENT
实验类型 综合性实验
实验课时 8学时
专业计算机科学与技术
班级
学号
学生姓名
嘉应学院计算机学院
2012年12月15日
一、实验目的3
二、实验内容与要求3
三、主要仪器设备3
四、实验内容4
4.1.实验基本功能:
在linux下用C语言编写,实现如下功能:
4
4.2主要代码编写:
4
4.2.1、实现服务器功能的主要代码编写:
4
4.2.2、实现客户端功能的主要代码编写13
五实验内容运行结果20
5.1实验简介20
5.2用make编译源文件从而产生可执行文件21
5.3运行服务器文件server21
5.4在另外一个终端运行客户端文件client21
5.5退出一步在文件夹外建立一个文件tmpftp22
5.6重新运行客户端,并下载文件tmpftp22
5.7重新启动客户端,并上传文件tmpftp22
5.8服务器端的运行情况22
六、实验总结23
一、实验目的
按照教学计划,本课程是在高级语言程序设计、数据结构、计算机网络等课程之后开设的。
要求初步掌握TCP/IP协议的体系结构;掌握网络编程开发流程;掌握基本的网络程序的编写方法,培养分析问题和解决问题的能力。
二、实验内容与要求
实验内容:
本课程的实验是一个综合性设计实验:
基于linux的FTPServer+client,通过本实验主要检验学生对TCP/IP网络协议的了解,阅读RFC959,熟悉ftp协议;进一步加强对C语言及linux系统调用的掌握,本实验涉及到:
linux系统、GCC、GDB、VI、linuxsocket网络编程、文件操作、流传输、进程控制与进程通信、存储管理、多线程技术等多方面专业知识的综合掌握情况。
实验要求:
1开发平台:
ubuntu11.04+vi+gcc
2、要求:
1)下载并认真阅读RFC959,了解FTP的具体内容、功能及标准;
2)实现FTP服务的基本功能,如获取目录内容、上传、下载、用户管理、文件管理、匿名登录等:
3)尽力实现扩展功能,如断点续传等。
三、主要仪器设备
1、已连接网络的计算机。
2、所使用的计算机安装了ubuntu版本的linux系统。
四、实验内容
4.1.实验基本功能:
在linux下用C语言编写,实现如下功能:
服务器端
客户端
数据的上传、下载
4.2主要代码编写:
Linux系统下,用文本编辑器编写ftp客户端与服务器端的C语言代码,另外几个包含的头文件。
下面是在ftp客户端和服务器功能实现中比较重要的代码。
4.2.1、实现服务器功能的主要代码编写:
Main主函数定义一些相关的变量等代码:
intmain(intargc,char**argv)
{
intsockfd;
intclientfd;
uint16_tport;
intret;
pid_tpid;
structsockaddr_inserver_addr;
if(2!
=argc){
printf("usage:
commandlisten_port\n");
return-1;
}
port=atoi(argv[1]);
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=INADDR_ANY;
server_addr.sin_port=htons(port);
sockfd=socket(PF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("opendatastreamsocketfailed!
\n");
return-1;
}
ret=bind(sockfd,(structsockaddr*)&server_addr,sizeof(server_addr));
if(ret<0)
{
perror("binddatasocketfailed!
\n");
return-1;
}
ret=listen(sockfd,SOMAXCONN);
if(ret<0)
{
perror("listeningdatastreamfailed!
\n");
return-1;
}
printf("正在等待客户端到链接...\n");
while
(1)
{
clientfd=accept(sockfd,NULL,NULL);
if(clientfd<0)
{
perror("acceptdataconnectionerror!
\n");
return-1;
}
pid=fork();
if(pid<0){
perror("forkerror!
\n");
}
if(0==pid){
//chidprocess
printf("oneclientcome...\n");
serv_client(clientfd);
return0;
}
close(clientfd);
}
}
处理服务器的请求
inthandle_request(msg_head_ctrl_t*msg,intsockfd);
voidserv_client(intsockfd)
{
msg_head_ctrl_t*msg;
ssize_tsize;;
uint32_tbody_len;
uint32_ttotal_len;
intret;
fd_setfs_client;
structtimevaltimeout;
等待服务器请求
while
(1){
FD_ZERO(&fs_client);
FD_SET(sockfd,&fs_client);
timeout.tv_sec=DEFAULT_TIME_OUT;
timeout.tv_usec=0;
ret=select(sockfd+1,&fs_client,NULL,NULL,&timeout);
if(0==ret){
//timeout
printf("timeout....\n");
return;
}
if(-1==ret){
continue;
}
接收服务器的请求信息
size=recv(sockfd,&body_len,sizeof(uint32_t),MSG_PEEK);
if(size<0){
printf("recvmsgerror!
\n");
return;
}
if(size==0){
printf("clientclosetheconnection\n");
return;
}
转换网络字节为本地字节
total_len=ntohl(body_len)+sizeof(msg_head_ctrl_t);
msg=malloc(total_len+1);
if(NULL==msg){
printf("mallocerror!
\n");
return;
}
memset(msg,0,total_len+1);
size=recv(sockfd,msg,total_len,0);
if(size!
=total_len){
printf("recvmsgbodyfailed!
\n");
return;
}
msg->body_len=ntohl(msg->body_len);
msg->command=ntohl(msg->command);
//printf("len=%d,msg=%s\n",msg->body_len,msg->msg_body);
如果服务器出现quit的时候就推出
if(COMMAND_QUIT==msg->command){
printf("clientclosedconnection!
\n");
close(sockfd);
return;
}
处理下载请求
ret=handle_request(msg,sockfd);
if(SOCK_ERROR==ret){
return;
}
free(msg);
}
}
处理客户端的下载
inthandle_get(msg_head_ctrl_t*msg,intsockfd)
{
intfd;
intret;
boolexist;
uint32_tbody_len;
msg_head_ctrl_t*ack_msg;
ssize_tread_bytes;
ssize_tsent_bytes;
检查所需下载的文件所否存在
exist=file_exist(msg->msg_body);
printf("%s,%d",msg->msg_body,exist);
if(false==exist){
printf("File%sdoesn'texist!
\n",msg->msg_body);
body_len=msg->body_len;
msg->body_len=htonl(msg->body_len);
msg->command=htonl(COMMAND_NO_FILE);
ret=send(sockfd,msg,sizeof(msg_head_ctrl_t)+body_len,0);
if((sizeof(msg_head_ctrl_t)+body_len)!
=ret){
printf("senderror,%s:
%d",__FUNCTION__,__LINE__);
returnSOCK_ERROR;
}
returnFAILED;
}
传送下载数据
while(true){
read_bytes=read(fd,ack_msg->msg_body,MAX_READ_BYTES);
if(read_bytes>0){
//printf("len%d,%d\n",read_bytes,ack_msg->body_len);
ack_msg->body_len=htonl(read_bytes);
ack_msg->command=htonl(msg->command);
ret=SUCCESSFUL;
}
elseif(-1==read_bytes){
read_bytes=0;
ack_msg->body_len=0;
ack_msg->command=htonl(COMMAND_ERROR_FILE);
ret=FAILED;
}
elseif(0==read_bytes){//传送完退出
ack_msg->body_len=0;
ack_msg->command=htonl(COMMAND_END_FILE);
ret=SUCCESSFUL;
}
sent_bytes=send(sockfd,ack_msg,read_bytes+sizeof(msg_head_ctrl_t),0);
if(sent_bytes!
=(read_bytes+sizeof(msg_head_ctrl_t))){
ret=SOCK_ERROR;
printf("senddataerror!
%s:
%d",__FUNCTION__,__LINE__);
break;
}
if(0==ack_msg->body_len){
break;
}
}
close(fd);
returnret;
}
处理显示服务端目录内容和打印服务端路径
inthandle_ls_pwd(msg_head_ctrl_t*msg,intsockfd)
{
FILE*file;
msg_head_ctrl_t*ack_msg;
size_tread_bytes;
size_tret;
printf("%s\n",msg->msg_body);
file=popen(msg->msg_body,"r");
if(NULL==file){
printf("executecommandfailed!
%s\n",msg->msg_body);
returnFAILED;
}
ack_msg=malloc(sizeof(msg_head_ctrl_t)+MAX_READ_BYTES);
if(NULL==ack_msg){
printf("outofmemory!
\n");
returnFAILED;
}
ack_msg->command=htonl(msg->command);
while(true){
read_bytes=fread(ack_msg->msg_body,1,MAX_READ_BYTES,file);
if(ferror(file)){
break;
}
ack_msg->body_len=htonl(read_bytes);
ret=send(sockfd,ack_msg,read_bytes+sizeof(msg_head_ctrl_t),0);
if((read_bytes+sizeof(msg_head_ctrl_t))!
=ret){
printf("sockerror!
\n");
returnSOCK_ERROR;
}
if(feof(file)){
printf("sendover!
\n");
break;
}
}
pclose(file);
}
处理服务器的请求
inthandle_request(msg_head_ctrl_t*msg,intsockfd)
{char*cmd;
intret;
switch(msg->command){
caseCOMMAND_CD:
//处理cd命令
cmd=trim_all_space(msg->msg_body+2);//skip"cd"charatcer
ret=chdir(cmd);
if(-1==ret){
printf("%s,|%s|\n",strerror(errno),cmd);
}
break;
caseCOMMAND_LS:
caseCOMMAND_PWD:
ret=handle_ls_pwd(msg,sockfd);
break;
caseCOMMAND_GET:
ret=handle_get(msg,sockfd);
break;
caseCOMMAND_PUT:
break;
default:
ret=FAILED;
break;
}
returnret;}
4.2.2、实现客户端功能的主要代码编写:
建立套接字
sockfd=socket(PF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("datastreamsocketcreatefailed!
\n");
return-1;
}
server.sin_family=AF_INET;
port=atoi(argv[2]);
server.sin_port=htons(port);
ret=inet_pton(AF_INET,argv[1],&server.sin_addr.s_addr);
if(ret<=0){
printf("youripaddressisunvalide!
\n");
usage();
return-1;
}
链接到服务端
ret=connect(sockfd,(structsockaddr*)&server,sizeof(structsockaddr_in));
if(ret<0)
{
perror("dataconnectionisfailed!
\n");
return-1;
}
printf("connecttoserversuccessfully!
\n");
clinet_process(sockfd);//客户端进程函数调用
}
处理服务端信息
inthandle_server_ack(sockfd)
{
intret;
uint32_tbody_len;
uint32_ttotal_len;
msg_head_ctrl_t*msg;
接受服务器端的请求
ret=recv(sockfd,&body_len,sizeof(body_len),MSG_PEEK);
if(ret<=0){
printf("connectionnlost...\n");
exit(-1);
}
body_len=ntohl(body_len);
total_len=body_len+sizeof(msg_head_ctrl_t);
msg=malloc(total_len+1);
if(NULL==msg){
perror("outofmemeory\n");
return;
}
memset(msg,0,total_len+1);
ret=recv(sockfd,msg,total_len,MSG_WAITALL);
if(ret<=0){
printf("connectionnlost...\n");
exit(-1);
}
msg->body_len=ntohl(msg->body_len);
msg->command=ntohl(msg->command);
if((COMMAND_LS==msg->command)||(COMMAND_PWD==msg->command)){
printf("\n%s\n",msg->msg_body);
}
elseif(COMMAND_GET==msg->command){
save_file_to_disk(msg->msg_body);
}
free(msg);
}
把命令传送到服务端
intsend_command_to_server(intsockfd,char*user_input,command_type_ttype)
{
ssize_tret;
msg_head_ctrl_t*msg;
intbody_len;
inttotal_len;
body_len=strlen(user_input);
total_len=body_len+sizeof(msg_head_ctrl_t);
msg=malloc(total_len);
if(NULL==msg){
printf("outofmemeory!
\n");
returnFAILED;
}
msg->command=htonl(type);
msg->body_len=htonl(body_len);
memcpy(msg->msg_body,user_input,body_len);
ret=send(sockfd,msg,total_len,0);
if(ret printf("connectionlost...\n"); free(msg); returnSOCK_ERROR; } free(msg); returnSUCCESSFUL; } 在客户端中下载文件功能 intget_file_from_server(intsockfd,char*user_input,command_type_ttype) { intret; intfd=-1; uint32_tlen; fd_setfs_client; structtimevaltimeout; msg_head_ctrl_t*msg; ret=send_command_to_server(sockfd,user_input,type); if(ret! =SUCCESSFUL){ returnret; } msg=malloc(sizeof(msg_head_ctrl_t)+MAX_READ_BYTES+1); if(NULL==msg){ printf("outofmemory! \n"); returnFAILED; } 传送下载数据 while(true){ FD_ZERO(&fs_client); FD_SET(sockfd,&fs_client); timeout.tv_sec=DEFAULT_CLIENT_TIME_OUT; timeout.tv_usec=0; select是处理多用户情况 ret=select(sockfd+1,&fs_client,NULL,NULL,NULL); if(0==ret){ //timeout printf("timeout....\n"); ret=SOCK_ERROR; break; } if(-1==ret){ continue; } memset(msg,0,sizeof(msg_head_ctrl_t)+MAX_READ_BYTES+1); ret=recv(sockfd,&len,sizeof(msg->body_len),MSG_PE
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux FTP 实验报告 实验 报告