tftp--实现服务器与客户端的下载与上传【转】

转自:https://blog.csdn.net/xiaopangzi313/article/details/9122975

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaopangzi313/article/details/9122975


项目功能:实现服务器与客户端的下载与上传,及linux系统下的tftp功能

项目名称:tftp--实现服务器与客户端的下载与上传

开发环境:linux /C

开发工具:GCC/GDB 

网络协议:TCP/IP

 

补充说明:程序中默认server端有upload文件夹用以接收client端上传的数据,client端有download文件夹用以下载server端的文件

开发流程:

 

编译流程:

1.cc    server.c  -o server

2.cc  client.c  -o client

 

运行l流程:

1.  ./server  192.168.1.207(server ip)  8888(port)

 2. ./client    192.168.1.207  8888  


调试效果:

client 端

 


server 端

 

 

1.server.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<signal.h>
#include<errno.h>
#include <dirent.h>


typedef struct {
char cmd[10];
int size;
char buf[1024];
}MSG;
MSG msg;
enum{list,get,put};
int do_list(int connect_fd)
{

char buf[1024];
int n;
int fd;
DIR *pdir;
struct dirent *pdirent;
if((pdir = opendir(".")) == NULL)
{
perror("Fail to open directory ");
exit(EXIT_FAILURE);
}
while((pdirent = readdir(pdir)) != NULL)
{
if(pdirent->d_name[0] == '.' )
continue;
strcpy(msg.buf,pdirent->d_name);
msg.size = strlen(msg.buf);
msg.size = send(connect_fd,&msg,sizeof(MSG),0);
}
msg.size = 0;
send(connect_fd,&msg,sizeof(MSG),0);
puts("send list successfully");
return 0;
}


int do_get(int connect_fd)
{
char filename[10];
int n;
int fd;
struct stat fileinfo;
if(recv(connect_fd,&msg,sizeof(MSG),0) < 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}

if(stat(msg.buf,&fileinfo) < 0)
{
perror("fail to stat");
msg.size = -1;
strcpy(msg.buf,strerror(errno));
send(connect_fd,&msg,sizeof(MSG),0);
return -1;
}
msg.size = fileinfo.st_size;
strcpy(filename,msg.buf);


puts("***********************");
printf("send file size : %d\n",msg.size);
printf("send filename : %s\n",msg.buf);
puts("***********************");

if(send(connect_fd,&msg,sizeof(MSG),0) < 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}

if((fd = open(msg.buf,O_RDONLY)) < 0)
{
fprintf(stderr,"Fail to open %s, %s\n",msg.buf,strerror(errno));
exit(EXIT_FAILURE);
}

while(1)
{
msg.size = read(fd, msg.buf,sizeof(msg.buf));
send(connect_fd,&msg,sizeof(MSG),0);
if(msg.size == 0)
break;
}
printf("send file %s successfully\n",filename);

return 0;
}
int do_put(int connect_fd)
{
char buf[1024];
int n;
int fd;
if(recv(connect_fd,&msg,sizeof(msg),0) <= 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}

puts("**********************************");
printf("upload filename : %s\n",msg.buf);
printf("size: %d\n",msg.size);
puts("**********************************");

strcpy(buf,"./upload/");
strcat(buf,msg.buf);
if((fd = open(buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
{
perror("Fail to accept");
exit(EXIT_FAILURE);
}
ftruncate(fd,msg.size);

while(1)
{
recv(connect_fd,&msg,sizeof(MSG),0);
write(fd,msg.buf,msg.size);
if(msg.size == 0)
break;
}
printf("send file successfully!\n");

exit(EXIT_SUCCESS);

}
int getcmd(char *pcmd)
{
if(strcmp(pcmd,"list") == 0)
return 0;
if(strcmp(pcmd,"get") == 0)
return 1;
if(strcmp(pcmd,"put") == 0)
return 2;
}
void do_task(int connect_fd,char *cmd)
{
MSG msg;

switch(getcmd(cmd))
{
case put:
printf("recv file from client...\n");
do_put(connect_fd);
break;
case get:
printf("send file to client...\n");
do_get(connect_fd);
break;
case list:
printf("send file list to client...\n");
do_list(connect_fd);
break;
default :
break;
}

return;
}
int do_client(int connect_fd)
{
MSG msg;
int n;
while(1)
{
if((n =recv(connect_fd,&msg,sizeof(msg),0) )< 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}
if(n == 0)
break;

do_task(connect_fd,msg.cmd);

}

exit(EXIT_FAILURE);
}
void signal_handler(int signum)
{
waitpid(-1,NULL,WNOHANG);
return;
}
int main(int argc, const char *argv[])
{
pid_t pid;
int listen_fd;
int connect_fd;
socklen_t addrlen;
struct sockaddr_in peer_addr;
struct sockaddr_in server_addr;
if(argc < 0)
{
perror("fail to argc");
exit(EXIT_FAILURE);

}
if(signal(SIGCHLD,signal_handler) == SIG_ERR)
{
perror("fail to signal");
exit(EXIT_FAILURE);
}
if((listen_fd = socket(AF_INET,SOCK_STREAM,0) )< 0)
{
perror("fail to socket");
exit(EXIT_FAILURE);
}
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr =inet_addr(argv[1]);
if(bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) //描述本机端口和IP,要知道数据包发往哪个进程
{
perror("Fail to bind");
exit(EXIT_FAILURE);
}

if(listen(listen_fd,8 ) < 0)//监听连接的套接字,接收各客户端的请求,返回监听套接字文件描述符
{
perror("Fail to listen");
exit(EXIT_FAILURE);
}
puts("listening ...");
addrlen = sizeof(peer_addr);
while(1)
{
if((connect_fd = accept(listen_fd,(struct sockaddr *)&peer_addr,&addrlen)) < 0)
{
perror("Fail to accept");//提取客户发过来的请求,返回新的已连接的套接字文件描述符
exit(EXIT_FAILURE);
}
puts("*************************");
printf("IP : %s\n",inet_ntoa(peer_addr.sin_addr));
printf("PORT : %d\n",ntohs(peer_addr.sin_port));
puts("*************************");
if((pid = fork()) < 0)
{
perror("Fail to listen");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
do_client(connect_fd);
}
close(connect_fd);
}
exit(EXIT_FAILURE);
}

 


2.client.c

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<errno.h>

typedef struct {
char cmd[10];
int size;
char buf[1024];
}MSG;

enum{list,get,put};
int do_list(client_fd,pname)
{
MSG msg;
int fd;
while(1)
{
recv(client_fd,&msg,sizeof(MSG),0);
if(msg.size == 0)
break;
printf("%s\n",msg.buf);
}
puts("get list successfully");
return 0;
}


int do_get(int client_fd,char *filename)
{
MSG msg;
int fd;
char buf[1024];
strcpy(msg.buf,filename);

if(send (client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to send");
exit(EXIT_FAILURE);
}

recv(client_fd,&msg,sizeof(MSG),0);
if(msg.size < 0)
{
printf("Error :%s \n",msg.buf);
return -1;
}

puts("***********************");
printf(" download file size : %d\n",msg.size);
printf(" download filename : %s\n",msg.buf);
puts("***********************");

strcpy(buf,"./download/");
strcat(buf,msg.buf);
if((fd = open(buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
{
fprintf(stderr,"Fail to open %s,%s\n",buf,strerror(errno));
exit(EXIT_FAILURE);
}

ftruncate(fd, msg.size);

while(1)
{
recv(client_fd,&msg,sizeof(MSG),0);
if(msg.size == 0)
break;
write(fd,msg.buf,msg.size);
}
printf("download file %s successfully\n",filename);
return 0;
}
int do_put(int client_fd,char *filename)
{
MSG msg;
int fd;
int n;
if((fd = open(filename,O_RDONLY)) < 0)
{
perror("Fail to open");
exit(EXIT_FAILURE);

}
msg.size = lseek(fd,0,SEEK_END);
strcpy(msg.buf,filename);
lseek(fd,0,SEEK_SET);

puts("**********************************");
printf("filename : %s\n",msg.buf);
printf("size :%d\n",msg.size);
puts("**********************************");

if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to send");
exit(EXIT_FAILURE);
}
while(1)
{

msg.size = read(fd,msg.buf,sizeof(msg.buf));
if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to read");
exit(EXIT_FAILURE);
}
if(msg.size == 0)
break;
}
printf("upload file successfully!\n");

return 0;
}
int getcmd(char *pcmd)
{
if(strcmp(pcmd,"list") == 0)
return 0;
if(strcmp(pcmd,"get") == 0)
return 1;
if(strcmp(pcmd,"put") == 0)
return 2;
}
int do_task(char *pcmd,char *pname,int client_fd)
{
MSG msg;
char buf[1024];
int fd;
switch(getcmd(pcmd))
{
case list:
printf("get file list from the server ...\n");
strcpy(msg.cmd,pcmd);

if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("FAIL to send");
exit(EXIT_FAILURE);
}
do_list(client_fd,pname);
break;
case get:
printf("file %s is downloading from server ...\n",pname);
strcpy(msg.cmd , pcmd);
if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("FAIL to send");
exit(EXIT_FAILURE);
}
do_get(client_fd,pname);
break;
case put:
printf(" file %s is uploading to server ...\n",pname);
strcpy(msg.cmd,pcmd);
if(send(client_fd,&msg,sizeof(MSG),0) < 0)
{
perror("Fail to send!");
exit(EXIT_FAILURE);
}
do_put(client_fd,pname);
break;

default:
break;

}
return 0;

}
int main(int argc, const char *argv[])
{
MSG msg;
char buf[1024];
char *pname,*pcmd;
int client_fd;
pid_t pid;
int connect_fd;
socklen_t addrlen;
struct sockaddr_in server_addr;

if((client_fd = socket(AF_INET,SOCK_STREAM,0) )< 0)
{
perror("fail to socket");
exit(EXIT_FAILURE);
}
memset(&server_addr,0,sizeof(server_addr));

server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr =inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));


if(connect(client_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
{
perror("Fail to accept");
exit(EXIT_FAILURE);
}

while(1)
{
printf("tftp>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf) -1] = '\0';
if(strncmp(buf,"quit",4) == 0)
break;
pcmd = strtok(buf," ");
pname = strtok(NULL," ");
do_task(pcmd,pname,client_fd);
}
exit(EXIT_FAILURE);




return 0;
}

---------------------
作者:xiaopangzi313
来源:CSDN
原文:https://blog.csdn.net/xiaopangzi313/article/details/9122975
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-04-28 14:00  Sky&Zhang  阅读(1582)  评论(0编辑  收藏  举报