📄 95-116.txt
字号:
if(pid==-1)
{
close(cmd_sockfd);
do_error(sockfd,"fork error");
}
else if(pid==0)//子进程处理流程
{
char who[20];
sprintf(who,"%s",inet_ntoa(their_addr.sin_addr));
printf('open connection with %s.\n",who);
run(cmd_sockfd,&their_addr);
printf("close connection with %s.\n",who);
}
//对于父进程,直接进入下一个循环
}
}
//SFTPLinuxClient.cpp:参数为服务器IP地址
#include <studio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include "define.h"
extern int errno;
//关闭文件描述符,打印错误信息,并退出程序:
void do_wrror(int fd,char *msg)
{
//close the valid file descriptor
if(fd>0)
close(fd)
//print out the error message
perror(msg);
exit(l);
}
//从给定的套接字fd中读取完整的回复报文:
void do_read(int fd,RspnsPacket *ptr)
{
int count=0;
int size=sizeof(RspnsPacket);
while(count<size)
{
int flag=read(fd,(char*)ptr+count,size-count);
if(flag==-1)
do_error(fd,"read response error");
count+=flag;
}
}
//发送命令报文:
void do_write_cmd(int fd,CmdPacket *ptr)
{
int size =sizeof(CmdPacket);
int flag=write(fd,(char*)ptr,size);
if(flag==-1)
do_error(fd,"write command error");
}
//从描述符fd读取数据,放至缓冲区buf中,并返回实际所读数据量:
int do_read_data(int fd,char *buf,int n)
{
int flag=read(fd,buf,n);
if(flag==-1)
do_error(fd,"read data error");
return flag;
}
//将缓冲区buf中内容写至描述符fd,并返回实际所写数据量:
int do_write_data(int fd,char *buf,int n)
{
int flag=write(fd,buf,n);
if(flag==-1)
do_error(fd,"write data error");
return flag;
}
//创建数据连接套接字,并进行侦听:
int create_data_socket()
{
int sockfd;
struct sockaddr_in my_addr;
int on=1;
//创建数据连接套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1
do_error(sockfd,"socket error in create_data_socket");
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on))==-1)\
do_error(sockfd,"setsockot error in create_data_socket");
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(DATA_PORT);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(my_addr.sin_zero),8);
//绑定到数据侦听端口
if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
do_error(sockfd,"bind error in create_data_socket");
//侦听数据连接请求
if(listen(sockfd,1)==-1)
do_error(sockfd,"listen error in create_data_socket");
return sockfd;
}
// 处理list命令:
void list (int sockfd,char *data_buf)
{
CmdPacket cmd_packet;
int newsockfd,data_sockfd;
struct sockaddr_in their_addr;
int sin_size;
//创建数据连接套接字,并进行侦听:
newsockfd=create_data_socket();
//先发送list命令报文:
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,(socklen_t*)&sin_size))==-1)
do_error(newsockfd,"accept error in get_file");
//从数据连接上循环读取数据并显示:
while(do_read_data(data_sockfd,data_buf,DATA_BUFSIZE)!=0)
printf("%s",data_buf);
close(data_socketfd);
close(newsockfd);
}
//处理pwd命令:
void pwd(int sockfd)
{
CmdPacket cmd_packet;
RspnsPacket rspns_packet;
//先发送pwd命令报文:
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;
//先发送cd命令报文:
cmd_packet.cmdid=CD;
scanf("%s",rspns_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(int sockfd,char *data_buf)
{
CmdPacket cmd_packet;
RspnsPacket rspns_packet;
int newsockfd,data_sockfd;
struct sockaddr_in their_addr;
int sin_size;
int fd,count;
cmd_packet.cmdid=GET;
scanf("%s",rspns_packet.param);
//创建文件:
fd=open(cmd_packet.param,O_WRONLY|O_CREAT|O_EXCL);
if(fd==-1)
{
if(errno==EEXIST)
printf("%s allready exists.\n",cmd_packet.param);
else
printf("Can't create file %s.\n",cmd_packet.param);
return;
}
//创建数据连接套接字并侦听数据连接请求:
newsockfd=create_data_socket();
//先在控制器连接中发送get命令报文:
do_write_cmd(sockfd,&rspns_packet);
//然后在控制连接中接收回复报文:
do_read_rspns(sockfd,&rspns_packet);
if(rspns_packet.rspnsid==ERR)
{
printf("%s",rspns+packet.text);
close(newsockfd);
close(fd);
remove(cmd_packet.param);
return;
}
//接收服务器的数据连接请求:
sin_size=sizeof(struct sockaddr_in);
if((data_sockfd=accept(newsockfd,(struct sockaddr *)&their_addr,(socklen_t*)&sin_size))==-1)
do_error(newsockfd,"accept error in get_file");
//循环地从数据中读取数据,并写入文件:
while((count=do_read_data(data_sockfd,data_buf,DATA_BUFSIZE))!=0)
do_write_data(fd,data_buf,count);
close(data_sockfd);
close(newsockfd);
close(fd);
}
//处理put命令:
void put_file(int sockfd,char *data_buf)
{
CmdPacket cmd_packet;
RspnsPacket rspns_packet;
int newsockfd,data_sockfd;
struct sockaddr_in their_addr;
int sin_size;
int fd,count;
cmd_packet.amdid=PUT;
scanf("s%",smd_packet.param);
// 打开文件:
fd=open(cmd_packet.param,O_PDONLY);
if(fd==-1)
{
if(erron==ENOENT)
printf("s%" id sn invalid path.\n",cmd_packet.param);
else
printf("Can't open file %s.\n",cmd_packet.param);
return;
}
//创建数据连接套接字并侦听数据连接请求:
newsockfd=create_data_socket();
// 先在控制连接中发送put命令报文;
do_write_cmd(sockfd,&cmd_packet);
//然后在控制连接中接收回复报文:
do_read_rsons(sdzassockfd,&rspns_packet);
if(rspns_packet.rspnsid==ERR)
{
printf("%s",rspns_packet.text);
close(newsockfd);
close(fd);
return;
}
sin_size=sizeof(struct sockaddr_in);
// 接收服务器的数据连接请求:
if((data_sockfd=accept(newsockfd,(struct sockaddr*)&their_addr,(socklen_t*)&sin_size))==-1)
do_error(newsockfd,"accept error in put_file");
//循环地从文件中读取数据,并写入数据连接;
while((count=do_read_data(fd,data_buf,DATA_BUFSIZE))!=0)
do_write_data(data_sockfd,data_buf,count);
//关闭数据连接套接字、数据连接侦听套接字和文件
close(data_sockfd);
close(newsockfd);
close(fd);
}
//处理quit命令:
void quit(int sockfd)
{
CmdPacket cmd_packet;
RspnsPacket rspns_packet;
//接收回复报文并显示其中的消息:
do_read_rspns(sockfd,&rspns_packet);
printf("%s",rspns_packet.text);
}
//客户端的主程序:
int main(int argc,char *argv[])
{
RspnsPacket rspns_packet;
int sockfd;
struct hostent *he;
struct sockaddr_in their_addr;
char cmd[10];
char data_buf[DATA_BUFSIZE];
if(argc!=2)
{
fprintf(stderr,"usage:SFTPClicent hostname(or IP address)\n");
exit(1);
]
//解析域名:
if((he=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname");
exit(1);
}
//创建控制连接套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
do_error(sockfd,"socket error");
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(CMD_PORT);
their_addr.sin_addr=*(struct in_addr *)he->h_addr;
bzero(&(their_addr.sin_zero),8);
//请求连接服务器:
if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr))==-1)
do_error(sockfd,"connect error");
//读取回复报文:
do_read_rsons(sockfd,&rspns_packet);
printf("%s",rspns_packet.text);
//主循环:读取输入命令并分派执行:
while (scanf("%s",cmd))
{
memset(data_buf,0,DATA_BUFSIZE);
switch(cmd[0])
{
case'1'://list命令
list(sockfd,data_buf);
break;
case'p':
if(cmd[1]=='w')//pwd命令
pwd(sockfd);
else//put命令
put_file (sockfd,data_buf);
break;
case'c'://cd命令
cd(sockfd);
break;
case'g'://get命令
get_file(sockfd,data_buf);
break;
case'q'://quit命令
quit(sockfd);
break;
defanlt;
printf(
"invalid command!\n");
break;
}
if(cmd[0]=='q')
break;
}
close(sockfd);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -