转自: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
",msg.size);
printf("send filename : %s
",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
",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
",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
",msg.buf);
printf("size: %d
",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!
");
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...
");
do_put(connect_fd);
break;
case get:
printf("send file to client...
");
do_get(connect_fd);
break;
case list:
printf("send file list to client...
");
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
",inet_ntoa(peer_addr.sin_addr));
printf("PORT : %d
",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
",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
",msg.buf);
return -1;
}
puts("***********************");
printf(" download file size : %d
",msg.size);
printf(" download filename : %s
",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
",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
",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
",msg.buf);
printf("size :%d
",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!
");
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 ...
");
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 ...
",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 ...
",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] = ' ';
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
版权声明:本文为博主原创文章,转载请附上博文链接!