项目要求:
基于tcp编写实现一个可以接收客户端的文件上传,下载,查看信号的服务器,
客户端通过输入“get filename”实现下载,
输入“put filename”实现上传,
输入“list”实现文件目录查看,
输入“quit”断开服务器。
服务器端
头文件(.h)
#ifndef _SERVER_H_
#define _SERVER_H_
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#define N 32
#define MAXSIZE 512
#define err_log(log)\
do{\
perror(log);\
exit(1);\
}while(0)
typedef struct sockaddr SA;
//目录文件显示
void process_list(int clientfd);
//下载文件
void process_get(int clientfd,const char *filename);
//上传文件
void process_put(int clientfd,const char *filename);
#endif
功能函数
#include "server.h"
//目录文件显示
void process_list(int clientfd)
{
DIR *fp = opendir("./");
if(fp == NULL)
err_log("opendir");
char buf[N]="";
struct dirent *sdir = readdir(fp);
while(sdir != NULL)
{
strcpy(buf,sdir->d_name);
if(buf[0] != '.')
{
if(send(clientfd,buf,sizeof(buf),0) == -1)
err_log("send");
}
bzero(buf,sizeof(buf));
sdir = readdir(fp);
}
strcpy(buf, "finish");
if(send(clientfd,buf,sizeof(buf),0) == -1)
err_log("send");
closedir(fp);
}
//文件下载
void process_get(int clientfd,const char *filename)
{
struct stat file_size;
char nexist[N] = "The file does not exist\n";
char exist[N] = "loading......\n";
char buf[MAXSIZE] = "0";
int ret = 0,reachnum = 0,count = 0;
int fd = open(filename,O_RDONLY);
if(fd == -1)
{
send(clientfd,nexist,sizeof(nexist),0);
return ;
}
else
{
send(clientfd,exist,sizeof(exist),0);
}
stat(filename,&file_size);
while(1)
{
bzero(buf,sizeof(buf));
ret = read(fd,buf,sizeof(buf));
count++;
send(clientfd,buf,ret,0);
if(ret <MAXSIZE)
{
printf("%s||send------over\n",filename);
break;
}
reachnum +=ret/file_size.st_size;
if(count == ((file_size.st_size/sizeof(buf))/4))
printf("%s||send------%d%%\n",filename,25);
else if(count == ((file_size.st_size/sizeof(buf))/2))
printf("%s||send------%d%%\n",filename,50);
else if(count == (((file_size.st_size/sizeof(buf))/4)*3))
printf("%s||send------%d%%\n",filename,75);
}
close(fd);
}
//文件上传
void process_put(int clientfd,const char *filename)
{
char buf[MAXSIZE] = "0";
int ret = 0;
int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0777);
if(fd == -1)
err_log("open");
while(1)
{
ret = recv(clientfd,buf,sizeof(buf),0);
if(ret == -1)
err_log("recv");
write(fd,buf,ret);
if(ret < MAXSIZE)
{
printf("%s||recv------over\n",filename);
break;
}
}
close(fd);
}
服务器main函数
#include "server.h"
int main(int argc, const char *argv[])
{
int serverfd,clientfd;
struct sockaddr_in serveraddr,clientaddr;
socklen_t len=sizeof(SA);
bzero(&serveraddr,len);
ssize_t bytes;
char buf[N]={0};
if(argc!=3)
{
fprintf(stderr,"User:%s IP PORT",argv[0]);
return -1;
}
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
if((serverfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
err_log("fail to socket");
}
if(bind(serverfd,(SA*)&serveraddr,len)<0)
{
close(serverfd);
err_log("fail to bind");
}
if(listen(serverfd,15)<0)
{
close(serverfd);
err_log("fail to listen");
}
while(1)
{
if((clientfd=accept(serverfd,(SA*)&clientaddr,&len))<0)
{
perror("fail to accept");
continue;
}
bytes=recv(clientfd,buf,N,0);
if(bytes<=0)
{
break;
}
switch(buf[0])
{
case 'L':
process_list(clientfd);
break;
case 'G':
process_get(clientfd,buf+2);
break;
case 'P':
process_put(clientfd,buf+2);
break;
}
close(clientfd);
}
close(serverfd);
return 0;
}
客户端
头文件(.h)
#ifndef _CLIENT_H_
#define _CLIENT_H_
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define N 32
#define MAXSIZE 512
#define err_log(log)\
do{\
perror(log);\
exit(1);\
}while(0)
typedef struct sockaddr SA;
//文件目录显示
void do_list(struct sockaddr_in serveraddr);
//文件下载
void do_get(struct sockaddr_in serveraddr,const char *filename);
//文件上传
void do_put(struct sockaddr_in serveraddr,const char *filename);
#endif
功能函数
#include "client.h"
//文件目录显示
void do_list(struct sockaddr_in serveraddr)
{
char buf[N] = "0";
int ret = 0;
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
err_log("socket");
ret = connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr));
if(ret == -1)
err_log("connect");
printf("********list********\n");
send(sockfd,"L",1,0);
while(1)
{
bzero(buf,sizeof(buf));
ret = recv(sockfd,buf,sizeof(buf),0);
if(ret == -1)
err_log("recv");
if(strcmp(buf,"finish") == 0)
{
printf("********finish********\n");
break;
}
printf("%s\n",buf);
}
}
//文件下载
void do_get(struct sockaddr_in serveraddr,const char *filename)
{
char namehand[N] = "G ";
strcat(namehand,filename);
char nexist[N] = "0";
char buf[MAXSIZE] = "0";
int ret = 0;
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
err_log("socket");
ret = connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr));
if(ret == -1)
err_log("connect");
send(sockfd,namehand,sizeof(namehand),0);
if(recv(sockfd,nexist,sizeof(nexist),0) == -1)
err_log("recv");
if(strcmp(nexist,"The file does not exist\n") == 0)
{
printf("The file does not exist\n");
return ;
}
int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC, 0777);
if(fd == -1)
err_log("open");
while(1)
{
bzero(buf,sizeof(buf));
ret = recv(sockfd,buf,sizeof(buf),0);
if(ret == -1)
err_log("recv");
write(fd,buf,ret);
if(ret < MAXSIZE)
{
printf("%s||recv------over\n",filename);
break;
}
}
close(fd);
}
//文件上传
void do_put(struct sockaddr_in serveraddr,const char *filename)
{
char namehand[N] = "P ";
strcat(namehand,filename);
struct stat file_size;
char buf[MAXSIZE] = "0";
int ret = 0,count = 0,reachnum = 0;
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
err_log("socket");
ret = connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr));
if(ret == -1)
err_log("connect");
int fd = open(filename, O_RDONLY);
if(fd == -1)
{
printf("The file does not exist\n");
return ;
}
stat(filename,&file_size);
send(sockfd,namehand,sizeof(namehand),0);
while(1)
{
ret = read(fd,buf,sizeof(buf));
if(ret == -1)
err_log("read");
send(sockfd,buf,ret,0);
if(ret <MAXSIZE)
{
printf("%s||send------over\n",filename);
break;
}
reachnum +=ret/file_size.st_size;
if(count == ((file_size.st_size/sizeof(buf))/4))
printf("%s||send------%d%%\n",filename,25);
else if(count == ((file_size.st_size/sizeof(buf))/2))
printf("%s||send------%d%%\n",filename,50);
else if(count == (((file_size.st_size/sizeof(buf))/4)*3))
printf("%s||send------%d%%\n",filename,75);
}
close(fd);
}
客户端主函数
#include "client.h"
int main(int argc, const char *argv[])
{
char buf[N]={0};
struct sockaddr_in serveraddr;
socklen_t len=sizeof(SA);
bzero(&serveraddr,len);
if(argc!=3)
{
fprintf(stderr,"User:%s IP PORT",argv[0]);
return 0;
}
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
while(1)
{
puts("***********************************************");
puts("1.list 2.get filename 3.put filename 4.quit");
puts("***********************************************");
puts("input cmd>>>");
fgets(buf,N,stdin);
buf[strlen(buf)-1]='\0';
switch(buf[0])
{
case 'l':
do_list(serveraddr);
break;
case 'g':
do_get(serveraddr,buf+4);
break;
case 'p':
do_put(serveraddr,buf+4);
break;
case 'q':
exit(0);
break;
default:
puts("cmd error");
break;
}
}
return 0;
}
如有不足,望指正,谢谢!!!