基于socket的ftp实现

服务器端的实现:
#include <sys/types.h>
#include <sys/socket.h>
#include<netinet/in.h>//sockaddr_in等结构的定义
#include<netdb.h>//addrinfo等结构的定义
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define TRUE 1
#define LISTEN_PORT 3499
#define dataLen 1024

char currentDirPath[200];
char currentDirName[30];
char help[]="get 
    get a file from server\n\
put      upload afile to server\n\
pwd      display      the current directory of server\n\
dir      displaythe files in the current directory of server\n\
cd      change thedirectory of server\n\
    display thewhole command which equals 'help'\n\
quit      return\n";

char *getDirName(char *dirPathName);
void cmd_pwd(int sock);
void cmd_dir(int sock);
void cmd_cd(int sock,char *dirName);
void cmd_cdback(int sock);
void cmd_help(int sock);
void cmd_get(int sock,char*fileName);
void cmd_put(int sock,char *fileName);
 
int main(int argc,char *argv[])
{
    int sock,sockmsg, length,lengthmsg;
    char client_cmd[10] ,cmd_arg[20];
    struct sockaddr_inserver;
    struct sockaddr_inservermsg;
    int datasock,msgsock;       
    pid_t child;
 
  // intdatasock;    //data socket
    int rval;
    sock=socket(AF_INET,SOCK_STREAM,0);//创建流式套接字
    sockmsg=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0||sockmsg<0)
    {
      perror("opening stream socket");
      exit(1);
    }
 
    server.sin_family=AF_INET;//AF_INET针对internet,另一种形式AF_UNIX只能够用于单一的Unix系统进程通信(主机通信协议)
    server.sin_addr.s_addr=INADDR_ANY;//表示可以和任何主机通信
    server.sin_port=htons(LISTEN_PORT);//htons将短整形数据转换位网络字节顺序

 
    servermsg.sin_family=AF_INET;
    servermsg.sin_addr.s_addr=INADDR_ANY;
    servermsg.sin_port=htons(LISTEN_PORT+1);

    if (bind(sock,(struct sockaddr*)&server,sizeofserver)<0||bind(sockmsg,(struct sockaddr*)&servermsg,sizeofservermsg)<0)//将本地端口与socket返回的文件描述符绑定在一起
    {
      perror("binding stream socket");
      exit(1);
    }
   
    length=sizeof server;
    lengthmsg=sizeofservermsg;
    if (getsockname(sock,(structsockaddr*)&server,&length)<0||getsockname(sockmsg,(structsockaddr*)&servermsg,&lengthmsg)<0)//用于得套接口的名字
    {
      perror("getting socket name");
      exit(1);
    }
 
    printf("Socket port #%d  %d\n",ntohs(server.sin_port),ntohs(servermsg.sin_port));

    memset(currentDirPath,0,sizeof(currentDirPath));//将currentDirpath置零
    getcwd(currentDirPath,sizeof(currentDirPath));//得到当前路径,保存在currentDirPath中
 
    listen(sock,2);//监听,允许最大监听数位2,将绑定的套接字变成监听套接字
    listen(sockmsg,2);
    do  
    {
        datasock = accept(sock,(structsockaddr*)0,(int*)0);//接受请求
        msgsock =accept(sockmsg,(struct sockaddr*)0,(int*)0);
        if (datasock ==-1||msgsock==-1)
            perror("accept");
        else
        {
            if((child=fork())==-1)//创建子进程
            {
                  printf("Fork Error!\n");
            }
            //The child process
            if(child==0)
            {
                  printf("connection accepted! new clientcomming\n");
loop:
                  memset(client_cmd,0,sizeof(client_cmd));
                  rval=0;
                  rval=read(msgsock,client_cmd,sizeof(client_cmd));//从msgsock中读取数据到client_cmd
 
                  if(rval<0)
                  {
                        perror("reading command failed\n");
                  }
                  else if(rval==0)
                  {
                        printf("connection closed.\n");
                        close(datasock);//关闭套接字
                        close(msgsock);
                  }
                  else
                  {
                        if(strcmp(client_cmd,"pwd")==0)
                        {
                              printf("cmmand pwd\n");
                              cmd_pwd(datasock);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"dir")==0)
                        {
                              printf("command dir\n");
                              cmd_dir(datasock);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"cd")==0)
                        {
                              printf("command cd\n");
                              //read the argument
                              memset(cmd_arg,0,sizeof(cmd_arg));
                              read(msgsock,cmd_arg,sizeof(cmd_arg));
                              cmd_cd(datasock,cmd_arg);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"cd..")==0)
                        {
                              printf("command cd..\n");
                              cmd_cdback(datasock);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"get")==0)
                        {
                              printf("command get\n");
 
                              memset(cmd_arg,0,sizeof(cmd_arg));
                              read(msgsock,cmd_arg,sizeof(cmd_arg));
                              cmd_get(datasock,cmd_arg);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"put")==0)
                        {
                              printf("command put\n");
 
                              memset(cmd_arg,0,sizeof(cmd_arg));
                              read(msgsock,cmd_arg,sizeof(cmd_arg));
                              cmd_put(datasock,cmd_arg);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"?")==0)
                        {
                              printf("command ?\n");

                              cmd_help(datasock);
                              printf("done\n\n");
                              goto loop;
                        }
                        else if(strcmp(client_cmd,"quit")==0)
                        {
                              printf("quit\n");
                              goto endchild;
                        }
                        else  
                        {
                              printf("bad request!\n");
                              goto loop;
                        }
                  }
endchild:
                  printf("connection closed.\n");
                  close(datasock);
                  close(msgsock);
                  exit(0);
            }
             
        }
    }while(TRUE);
 
    exit(0);
}

//pwd command
void cmd_pwd(int sock)
{
      intlen;
      memset(currentDirPath,0,sizeof(currentDirPath));
      getcwd(currentDirPath,sizeof(currentDirPath));
      char*savePointer=getDirName(currentDirPath);
      strcpy(currentDirName,savePointer);
      len=strlen(currentDirName)+1;
      write(sock,currentDirName,len);
}

//dir command
void cmd_dir(int sock)
{
      DIR *pdir;//目录结构
      charfileName[30];
      charfileInfo[50];
      int i,fcounts=0, len;
      structdirent *pent;//目录的结构体属性
      intfd;
      struct statfileSta;//文件属性
      charfilePath[200];
     
      pdir=opendir(currentDirPath);//打开目录
      pent=readdir(pdir);//读取目录
     
      while(pent!=NULL)
      {
            fcounts++;//计算文件个数
            pent=readdir(pdir);
      }

      write(sock,&fcounts,sizeof(int));//将文件个数写入sock
      closedir(pdir);//关闭目录

      if(fcounts<=0)
      {
            return;
      }
      else
      {
            pdir=opendir(currentDirPath);
            for(i=0;i<fcounts;i++)
            {
                  pent=readdir(pdir);
                  memset(fileName,0,30);
                  memset(fileInfo,0,sizeof(fileInfo));
                  strcpy(fileName,pent->d_name);
                 
                  //check the file is a directory or a file
                  memset(filePath,0,sizeof(filePath));
                  strcpy(filePath,currentDirPath);
                  strcat(filePath,"/");//链接两个字符串
                  strcat(filePath,fileName);
                  fd=open(filePath,O_RDONLY, S_IREAD);
                 
                  fstat(fd,&fileSta);//用来读取打开的文件的属性,stat用来读取没有打开的文件的属性
                  if(S_ISDIR(fileSta.st_mode))//判断文件是否为目录
                  {
                        strcat(fileInfo,"dir\t");
                        strcat(fileInfo,fileName);
                  }
                  else
                     
                        strcat(fileInfo,"file\t");
                        strcat(fileInfo,fileName);
                  }
                  write(sock,fileInfo,sizeof(fileInfo));
            }
            closedir(pdir);
      }
     
     
}

//command cd
void cmd_cd(int sock,char *dirName)
{
      DIR*pdir;
      structdirent *pent;
      charfilename[30];
      inti,fcounts=0;
      intflag=0;

      pdir=opendir(currentDirPath);
      pent=readdir(pdir);
     
      while(pent!=NULL)
      {
            fcounts++;
            pent=readdir(pdir);
      }

      closedir(pdir);

      if(fcounts<=0)
      {
            return;
      }
      else
      {
            pdir=opendir(currentDirPath);
            for(i=0;i<fcounts;i++)
            {
                  pent=readdir(pdir);
                  if(strcmp(pent->d_name,dirName)==0)
                  {
                        strcat(currentDirPath,"/");
                        strcat(currentDirPath,dirName);
                        flag=1;
                        break;
                  }
            }
           
            if(flag==1)
            {
                  write(sock,currentDirPath,sizeof(currentDirPath));
            }
            closedir(pdir);
      }
     
     
}

//command cd..
void cmd_cdback(int sock)
{
      intlen;
      int i,record;

      len=strlen(currentDirPath);
     
      for(i=len-1;i>=0;i--)
      {
            if(currentDirPath[i]=='/')
            {
                  currentDirPath[i]='\0';
                  break;
            }
            currentDirPath[i]='\0';
      }
}
//command ?
void cmd_help(int sock)
{
      intlen=strlen(help)+1;
      write(sock,help,len);
}

//command get
void cmd_get(int sock,char*fileName)
{
      intfd;
      struct statfileSta;
      longfileSize;
      charfilePath[200], buf[dataLen];
     
      memset(filePath,0,sizeof(filePath));
      strcpy(filePath,currentDirPath);
      strcat(filePath,"/");
      strcat(filePath,fileName);

      fd=open(filePath,O_RDONLY, S_IREAD);
      if(fd!=-1)
      {
            fstat(fd,&fileSta);
            fileSize=(long) fileSta.st_size;//?
            write(sock,&fileSize,sizeof(long));
            memset(buf,0,dataLen);
            while(fileSize>dataLen)
            {
                  read(fd,buf,dataLen);
                  write(sock,buf,dataLen);
                  fileSize=fileSize-dataLen;
            }
           
            read(fd,buf,fileSize);
            write(sock,buf,fileSize);
            close(fd);
            printf("transfer completed\n");
      }
      else
      {
            printf("open file %s failed\n",filePath);
         
}

//command put
void cmd_put(int sock,char *fileName)
   
      intfd;
      longfileSize;
     
      charfilePath[200], buf[dataLen];
      strcpy(filePath,currentDirPath);
      strcat(filePath,"/");
      strcat(filePath,fileName);
     

      fd=open(filePath,O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
      if(fd!=-1)
         
            memset(buf,0,dataLen);
            read(sock,&fileSize,sizeof(long));

            while(fileSize>dataLen)
            {
                  read(sock,buf,dataLen);
                  write(fd,buf,dataLen);
                  fileSize=fileSize-dataLen;
            }
           
            read(sock,buf,fileSize);
            write(fd,buf,fileSize);
            close(fd);
            printf("transfer completed\n");
      }
      else
      {
            printf("open file %s failed\n",filePath);
      }
     
}

//get the last string after the last char '/'
char *getDirName(char *dirPathName)
{
      int i, pos,len;
      char*dirName;

      if(dirPathName==NULL)
      {
            printf("directory absoultly path isnull!\n");
            return NULL;
         
     
      len=strlen(dirPathName);
      for(i=len-1;i>=0;i--)
      {
            if(dirPathName[i]=='/')
            {
                  pos=i;
                  break;
            }
      }
     
      dirName=(char *)malloc(len-pos+1);
      for(i=pos+1;i<len;i++)
      {
            dirName[i-pos-1]=dirPathName[i];     
      }
     
      returndirName;
}
客户端实现:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>

#define TRUE 1
#define dataLen 1024
char user_cmd[10],cmd_arg[20];
char buf[dataLen];

void cmd_pwd(int sock,int sockmsg);
void cmd_dir(int sock,int sockmsg);
void cmd_cd(int sock,int sockmsg,char *dirName);
void cmd_cdback(int sock,int sockmsg);
void cmd_help(int sock,int sockmsg);
void cmd_get(int sock,int sockmsg,char *fileName);
void cmd_put(int sock,int sockmsg,char *fileName);
void cmd_quit(int sock,int sockmsg);
 
int main(int argc,char *argv[])
{
  int cmd_len,arg_len;
  int sock, sockmsg;
  struct sockaddr_in server, servermsg;
  struct hostent *hp;
   
  sock=socket(AF_INET,SOCK_STREAM,0);
  sockmsg=socket(AF_INET,SOCK_STREAM,0);
       
  if(sock<0||sockmsg<0)
  {
      perror("opening stream socket");
      exit(1);
  }
 
  hp = gethostbyname(argv[1]);
  if (hp==0)
  {
      fprintf(stderr,"%s:unknown host\n",argv[1]);
      exit(2);
  }
 
  server.sin_family=AF_INET;
  server.sin_port=htons(atoi(argv[2]));
  memcpy((char*)&server.sin_addr,(char*)hp->h_addr,hp->h_length);
 
  servermsg.sin_family=AF_INET;
  servermsg.sin_port=htons(atoi(argv[2])+1);
  memcpy((char*)&servermsg.sin_addr,(char*)hp->h_addr,hp->h_length);
 
  if (connect(sock,(struct sockaddr*)&server,sizeofserver)<0||connect(sockmsg,(struct sockaddr*)&servermsg,sizeofservermsg)<0)
  {
        perror("connecting stream socket");
      exit(1);
  }
 
 
  //Get command from command line and do just theaction
  while(TRUE)
  {
      memset(user_cmd,0,10);
      memset(cmd_arg,0,20);

      //First getthe input character by user
      printf("command: ");
      scanf("%s",user_cmd);
      cmd_len=strlen(user_cmd);
      //Then getthe command character and the argument
      if(strcmp(user_cmd,"quit")==0)            //command"quit"
      {
            cmd_quit(sock,sockmsg);
            close(sockmsg);
            close(sock);
            printf("connection closed\n\n");
            exit(0);
           
      elseif(strcmp(user_cmd,"?")==0)        //command"?"
      {
            cmd_help(sock,sockmsg);
      }
      elseif(strcmp(user_cmd,"pwd")==0)      //command"pwd"
      {
            cmd_pwd(sock,sockmsg);
      }
      elseif(strcmp(user_cmd,"dir")==0)        //command"dir"
      {
            cmd_dir(sock,sockmsg);
      }
      elseif(strcmp(user_cmd,"cd")==0)      //commad "cd"
      {
            //inputcommand argument
            scanf("%s",cmd_arg);
            cmd_cd(sock,sockmsg,cmd_arg);
      }
      elseif(strcmp(user_cmd,"cd..")==0)
      {
            cmd_cdback(sock,sockmsg);
      }
      elseif(strcmp(user_cmd,"get")==0)      //command "get"
      {
            //inputcommand argument
            scanf("%s",cmd_arg);
            cmd_get(sock,sockmsg,cmd_arg);
      }
      elseif(strcmp(user_cmd,"put")==0)      //command "put"
         
            //inputcommand argument
            scanf("%s",cmd_arg);
            cmd_put(sock,sockmsg,cmd_arg);
      }
      else
      {
            printf("badcommand!\n");
      }
 
 
}

//command pwd
void cmd_pwd(int sock,int sockmsg)
{
      //intnumRead;
      chardirName[30];
      write(sockmsg,user_cmd,sizeof(user_cmd));
      read(sock,dirName,30);
      printf("%s\n",dirName);
}

//command dir
void cmd_dir(int sock, int sockmsg)
{
      int i,fileNum=0;
      charfileInfo[50];
     
      write(sockmsg,user_cmd,sizeof(user_cmd));
      read(sock,&fileNum,sizeof(int));

      printf("--------------------------------------------------------\n");
      printf("filenumber : %d\n",fileNum);
      if(fileNum>0)
      {
            for(i=0;i<fileNum;i++)
            {
                  memset(fileInfo,0,sizeof(fileInfo));
                  read(sock,fileInfo,sizeof(fileInfo));
                  printf("%s\n",fileInfo);
            }
            printf("--------------------------------------------------------\n");
      }
      elseif(fileNum==0)
      {
            printf("directory of server point is empty.\n");
            return;
      }
      else
      {
            printf("error in command 'dir'\n");
            return;
      }
}

//command cd
void cmd_cd(int sock,int sockmsg,char *dirName)
{
      charcurrentDirPath[200];
      write(sockmsg,user_cmd,sizeof(user_cmd));
      write(sockmsg,cmd_arg,sizeof(cmd_arg));
      read(sock,currentDirPath,sizeof(currentDirPath));
     
      printf("nowin directory : %s\n",currentDirPath);
}

//command cd..
void cmd_cdback(int sock,int sockmsg)
{
      write(sockmsg,user_cmd,sizeof(user_cmd));     
}
//command quit
void cmd_quit(int sock,int sockmsg)
{
      write(sockmsg,user_cmd,sizeof(user_cmd));
}

//command help
void cmd_help(int sock, int sockmsg)
{
      charhelp[300];
      write(sockmsg,user_cmd,sizeof(user_cmd));
      read(sock,help,300);
     
      printf("%s\n",help);     
}

//command get
void cmd_get(int sock,int sockmsg,char *fileName)
{
      intfd;
      longfileSize;
      charlocalFilePath[200];

      write(sockmsg,user_cmd,sizeof(user_cmd));
      write(sockmsg,cmd_arg,sizeof(cmd_arg));
      printf("%s\n%s\n",user_cmd,cmd_arg);
     
      memset(localFilePath,0,sizeof(localFilePath));
      getcwd(localFilePath,sizeof(localFilePath));
      strcat(localFilePath,"/");
      strcat(localFilePath,fileName);

      fd=open(localFilePath,O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
      if(fd!=-1)
         
            memset(buf,0,dataLen);
            read(sock,&fileSize,sizeof(long));
            while(fileSize>dataLen)
            {
                  read(sock,buf,dataLen);
                  write(fd,buf,dataLen);
                  fileSize=fileSize-dataLen;
            }
           
            read(sock,buf,fileSize);
            write(fd,buf,fileSize);
            close(fd);
            printf("download completed\n");
      }
      else
      {
            printf("openfile %s failed\n",localFilePath);
      }
}

//command put
void cmd_put(int sock,int sockmsg,char* fileName)
   
      write(sockmsg,user_cmd,sizeof(user_cmd));
      write(sockmsg,cmd_arg,sizeof(cmd_arg));
     
      intfd;
      longfileSize;
      intnumRead;
      charfilePath[200];
      struct statfileSta;

      memset(filePath,0,sizeof(filePath));
      getcwd(filePath,sizeof(filePath));
     
      strcat(filePath,"/");
      strcat(filePath,fileName);
     
      fd=open(filePath,O_RDONLY, S_IREAD);

      if(fd!=-1)
      {
            fstat(fd,&fileSta);
            fileSize=(long) fileSta.st_size;

            write(sock,&fileSize,sizeof(long));
            memset(buf,0,dataLen);
            while(fileSize>dataLen)
            {
                  read(fd,buf,dataLen);
                  write(sock,buf,dataLen);
                  fileSize=fileSize-dataLen;
            }
           
            read(fd,buf,fileSize);
            write(sock,buf,fileSize);
            close(fd);
            printf("upload completed\n");
      }
      else
      {
            printf("openfile %s failed\n",filePath);
         
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值