Linux下实现FTP服务器

功能需求:

远程操作:
①获取服务器的文件: get xxx
②显示服务器有哪些文件: ls
③进入服务器某文件夹: cd xxx;
④上传文件到服务器: put xxx
⑤打印当前服务器路径: pwd
⑥退出服务器: quit
 本地操作:
①查看客户端本地文件: lls
②进入客户端文件夹: lcd

 实现的基本思路:

查看本地文件lls:可以直接使用system函数直接调用;显示服务器文件ls:则可以通过socket套接字来实现数据传输,然后用popen函数运行服务器ls这个api再通过read函数将ls展开的数据读出来,再通过write函数写到客户端,put、get均是以上思路

代码实现

 头文件 server.h

#define LS   0
#define CD   1
#define PWD  2
#define GET  3

#define IFRET 4

#define LLS  5
#define LCD  6
#define PUT  7
#define QUIT   8
#define DOFILE 9


struct Msg                                  //传递的信息结构体
{
        int type ;                  //服务器返回类型,0表示不用返回,1表示字符串,DOFILE表示要创建文件
        char data[32];    //指令
        char secondBuf[10240];//数据,用于server和client间的通信

};

服务器代码

socket套接字->bind绑定网络地址和端口号->listen监听->while循环 accept阻塞等待客户端连接->如果有客户端连接,就fork()产生子进程来对接客户端(一个客户端一个子进程)->read读客户端发送的请求命令,如果读到了命令,就进入msghandler函数处理命令

#include<stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include<linux/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <string.h>
#include <unistd.h>
#include"config.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>



/*struct sockaddr_in {
		sa_family_t sin_family;		//协议族
		in_port_t 	sin_port;		//端口号
		struct in_addr sin_addr;		//IP地址结构体
		unsigned char	sin_zero[8];	//填充,没有实际意义,只是为更sockaddr结构在内存中相互对齐,这样才能相互转换

}*/



/*struct in_addr {
        __be32  s_addr;
};*/

char* getdestdir(char *cmd)
{
  char* p = NULL;
  p=strtok(cmd," ");
  p=strtok(NULL," ");
  return p;
}

int get_cmd_type(char *cmd)
{
  if(!strcmp("ls",cmd))   return LS;
  if(!strcmp("lls",cmd))  return LLS;
  if(!strcmp("pwd",cmd))  return PWD;
  if(!strcmp("quit",cmd))  return QUIT;

  if(strstr(cmd,"get")!=NULL) return GET;
  if(strstr(cmd,"put")!=NULL) return PUT;
  if(strstr(cmd,"cd")!=NULL) return CD;
  if(strstr(cmd,"lcd")!=NULL) return LCD;
  
  return -1;
}

int msghandler(int fd , struct Msg msg)
{
  char* file;
  char* dir;
  char readbuf[1024]={0};
  int fdfile;
  int ret = get_cmd_type(msg.data);
  switch(ret){
      case LS:
      case PWD:
           msg.type = 1;
           FILE* r=popen(msg.data,"r");//popen是执行msg.data的命令然后将执行结果返回给FILE*r
           fread(msg.secondBuf,sizeof(msg.secondBuf),1,r);//将r中的结果读到msg.secondBuf中
           write(fd,&msg,sizeof(msg));//将整个结构体再通过管道发回给客户端
           break;
      case LLS:
           msg.type = 1;
           write(fd,&msg,sizeof(msg));
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值