⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 ftp客户端
💻 C
字号:
//SFTPWinClient.cpp 参数为服务器地址
#include<stdio.h>
#include<winsock2.h>
#include<windows.h>
#include<iostream.h>
#pragma   comment(lib,"ws2_32.lib") 

#include"define.h"

void help()
{ 
 cout<<"**************COMMANDS available*******************"<<endl
  <<"*   ls...........................list of the dir  *"<<endl
  <<"*   cd...........................get in a dir     *"<<endl
  <<"*   rec..........................receive a file   *"<<endl
  <<"*   send.........................send a file      *"<<endl
  <<"*   quit.........................quit the program *"<<endl
  <<"***************************************************"<<endl;
}
//读取回复报文
void do_read_rspns(SOCKET fd,RspnsPacket *ptr)
{
 int count=0;
 int size=sizeof(RspnsPacket);
 while(count<size)
 {
  int nRead=recv(fd,(char*)ptr+count,size-count,0);
  if(nRead<=0)
  {
   printf("read response error");
   closesocket(fd);
   exit(1);
  }
  count+=nRead;
 }
}

//发送命令报文
void do_write_cmd(SOCKET fd,CmdPacket *ptr)
{
 int size=sizeof(CmdPacket);
 int flag=send(fd,(char *)ptr,size,0);
 if(flag==SOCKET_ERROR)
 {
  printf("write command error");
  closesocket(fd);
  WSACleanup();
  exit(1);
 }
}

//创建数据连接套接字并进入侦听状态
SOCKET create_data_socket()
{
 SOCKET sockfd;
 struct sockaddr_in my_addr;
 
 //创建用于数据连接的套接字
 if((sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
 {
  printf("socket error in create_data_socket");
  WSACleanup();
  exit(1);
 }

 my_addr.sin_family=AF_INET;
 my_addr.sin_port=htons(DATA_PORT);
 my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
 memset(&(my_addr.sin_zero),0,sizeof(my_addr.sin_zero));

 //绑定
 if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==SOCKET_ERROR)
 {
  int err=WSAGetLastError();
  printf("bind error %d in create_data_socket!\n",err);
  closesocket(sockfd);
  WSACleanup();
  exit(1);
 }

 //侦听数据连接请求
 if(listen(sockfd,1)==SOCKET_ERROR)
 {
  printf("listen error in create_data_socket");
  closesocket(sockfd);
  WSACleanup();
  exit(1);
 }
 return sockfd;
}

//处理list命令
void list(SOCKET sockfd)
{
 int sin_size;
 int nRead;
 CmdPacket cmd_packet;
 SOCKET newsockfd,data_sockfd;
 struct sockaddr_in their_addr;
 char data_buf[DATA_BUFSIZE];

 //创建数据连接
 newsockfd=create_data_socket();

 //构建命令报文并发送至服务器
 cmd_packet.cmdid=LS;//没有参数
 do_write_cmd(sockfd,&cmd_packet);
 sin_size=sizeof(struct sockaddr_in);
 //接受服务器的数据连接请求
 if((data_sockfd=accept(newsockfd,(struct sockaddr *)&their_addr,&sin_size))==INVALID_SOCKET)
 {
  printf("accept error itn get_file");
  closesocket(newsockfd);
  closesocket(sockfd);
  WSACleanup();
  exit(1);
 }

 //每次读到多少数据就显示多少,直到数据连接断开
 while(true)
 {
  nRead=recv(data_sockfd,data_buf,DATA_BUFSIZE-1,0);
  if(nRead==SOCKET_ERROR)
  {
   printf("read response error!\n");
   closesocket(data_sockfd);
   closesocket(newsockfd);
   closesocket(sockfd);
   WSACleanup();
   exit(1);
  }
  if(nRead==0)//数据读取结束
   break;

  //显示数据
  data_buf[nRead]='\0';
  printf("%s",data_buf);
 }
 closesocket(data_sockfd);
 closesocket(newsockfd);
}
//处理pwd命令
void pwd(int sockfd)
{
 CmdPacket cmd_packet;
 RspnsPacket rspns_packet;
 cmd_packet.cmdid=PWD;
 //发送命令报文并读取回复
 do_write_cmd(sockfd,&cmd_packet);
 do_read_rspns(sockfd,&rspns_packet);
 printf("%s\n",rspns_packet.text);
}

//处理cd命令
void cd(int sockfd)
{
 CmdPacket cmd_packet;
 RspnsPacket rspns_packet;

 cmd_packet.cmdid=CD;
 scanf("%s",cmd_packet.param);

 //发送命令报文并读取回复
 do_write_cmd(sockfd,&cmd_packet);
 do_read_rspns(sockfd,&rspns_packet);
 if(rspns_packet.rspnsid==ERR)
  printf("%s",rspns_packet.text);
}

//处理get命令,即下载文件
void get_file(SOCKET sockfd)
{
 FILE *fd;
 char data_buf[DATA_BUFSIZE];

 CmdPacket cmd_packet;
 RspnsPacket rspns_packet;

 SOCKET newsockfd,data_sockfd;
 struct sockaddr_in their_addr;
 int sin_size;
 int count;

 //设置命令报文
 cmd_packet.cmdid=GET;
 scanf("%s",cmd_packet.param);

 //打开或创建本地文件以供写数据
 fd=fopen(cmd_packet.param,"wb");//使用二进制方式
 if(fd==NULL)
 {
  printf("open file %s for weite failed!\n",cmd_packet.param);
  return;
 }

 //创建数据连接并侦听服务器的连接请求
 newsockfd=create_data_socket();
 //发送命令报文
 do_write_cmd(sockfd,&cmd_packet);
 //读取回复报文
 do_read_rspns(sockfd,&rspns_packet);
 if(rspns_packet.rspnsid==ERR)
 {
  printf("%s",rspns_packet.text);
  closesocket(newsockfd);
  fclose(fd);
  //删除文件
  DeleteFile(cmd_packet.param);
  return;
 }
 sin_size=sizeof(struct sockaddr_in);
 //等待接受服务器的连接请求
 if((data_sockfd=accept(newsockfd,(struct sockaddr *)&their_addr,&sin_size))==INVALID_SOCKET)
 {
  printf("accept error int get_file!\n");
  closesocket(newsockfd);
  fclose(fd);
  //删除文件
  DeleteFile(cmd_packet.param);
  return;
 }
 //循环读取网络数据并写入文件
 while((count=recv(data_sockfd,data_buf,DATA_BUFSIZE,0))>0)
  fwrite(data_buf,sizeof(char),count,fd);

 closesocket(data_sockfd);
 closesocket(newsockfd);
 fclose(fd);
}

//处理put命令,即上传文件
void put_file(SOCKET sockfd)
{
 FILE *fd;
 CmdPacket cmd_packet;
 RspnsPacket rspns_packet;
 char data_buf[DATA_BUFSIZE];

 SOCKET newsockfd,data_sockfd;
 struct sockaddr_in their_addr;
 int sin_size;
 int count;

 cmd_packet.cmdid=PUT;
 scanf("%s",cmd_packet.param);

 //打开本地文件用于读数据
 fd=fopen(cmd_packet.param,"rb");
 if(fd==NULL)
 {
  printf("open %s for reading failed!\n",cmd_packet.param);
  return;
 }

 //创建数据连接套接字并进入侦听状态
 newsockfd=create_data_socket();

 //发送命令报文
 do_write_cmd(sockfd,&cmd_packet);

 //读取回复报文
 do_read_rspns(sockfd,&rspns_packet);
 if(rspns_packet.rspnsid==ERR)
 {
  printf("%s",rspns_packet.text);
  closesocket(newsockfd);
  fclose(fd);
  return;
 }

 sin_size=sizeof(struct sockaddr_in);
 //准备接受数据连接请求
 if((data_sockfd=accept(newsockfd,(struct sockaddr *)&their_addr,&sin_size))==INVALID_SOCKET)
 {
  printf("accept error int put_file!\n");
  closesocket(newsockfd);

  fclose(fd);
  return;
 }

 //循环从文件中读取数据并发给服务器
 while(true)
 {
  count=fread(data_buf,sizeof(char),DATA_BUFSIZE,fd);
  send(data_sockfd,data_buf,count,0);
  if(count<DATA_BUFSIZE)//数据已经读完或发生错误
   break;
 }
 closesocket(data_sockfd);
 closesocket(newsockfd);
 fclose(fd);
}
//处理退出命令
void quit(int sockfd)
{
 CmdPacket cmd_packet;
 RspnsPacket rspns_packet;
 cmd_packet.cmdid=QUIT;
 do_write_cmd(sockfd,&cmd_packet);
 do_read_rspns(sockfd,&rspns_packet);
 printf("%s",rspns_packet.text);
}
void main()
{
 char *argvv[20];
 for(int i=0;i<20;i++)
 {
  argvv[i]='\0';
 }
 cout<<"please input the host IP:"<<endl;
 cin>>*argvv;
 int argc=2;
 SOCKET sockfd;
 struct hostent *he;
 struct sockaddr_in their_addr;
 char cmd[10];
 RspnsPacket rspns_packet;

 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 if(argc!=2)
 {
  printf("usage:sftpclient hostname(or IP address)\n");
  exit(1);
 }

 wVersionRequested=MAKEWORD(2,2);
 //winsock初始化
 err=WSAStartup(wVersionRequested,&wsaData);
 if(err!=0)
 {
  printf("winsock initialized failed!\n");
  return;
 }

 //确认winsock dll版本是2.2
 if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
 {
  printf("winsock version is not 2.2\n");
  WSACleanup();
  return;
 }

 //创建用于控制连接的socket
 sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 if(sockfd==INVALID_SOCKET)
 {
  printf("failed to create socket!\n");
  WSACleanup();
  exit(1);
 }
 if((he=gethostbyname(argvv[1]))==NULL)
 {
  printf("gethostbyname failed!");
  exit(1);
 }
 their_addr.sin_family=AF_INET;
 their_addr.sin_port=htons(CMD_PORT);
 their_addr.sin_addr=*(struct in_addr *)he->h_addr_list[0];
 memset(&(their_addr.sin_zero),0,sizeof(their_addr.sin_zero));
 //连接服务器
 if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr))==SOCKET_ERROR)
 {
  printf("connect error");
  closesocket(sockfd);
  WSACleanup();
  exit(1);
 }

 //连接成功后,首先接受服务器发回的消息
 do_read_rspns(sockfd,&rspns_packet);
 printf("%s",rspns_packet.text);

 //主循环 读取用户输入并分派执行
 while(true)
 {
  scanf("%s",cmd);
  switch(cmd[0])
  {
  case'l'://处理list命令
   list(sockfd);
   break;
  case'p':
   pwd(sockfd);
   break;
  case's': //send
   put_file(sockfd);
   break;
  case'c'://处理cd命令
   cd(sockfd);
   break;
  case'r'://处理rec命令
   get_file(sockfd);
   break;
  case'q'://处理quit命令
   quit(sockfd);
   break;
  case'h':
   help();
   break;
  default:
   printf("invalid command!\n");
   break;
  }
  if(cmd[0]=='q')
   break;
 }
 WSACleanup();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -