您的位置:首页 > 理论基础 > 计算机网络

linux 网络编程 Tcp文件服务器

2017-06-21 12:51 393 查看
参考链接:http://blog.csdn.net/yanghaoran321/article/details/7882760



程序功能:

     客户端能够通过命令显示文件服务器上的文件,能够上传、下载文件等等功能;

在浏览原博主的代码后,作出一下修改:

 将迭代服务器修改为 并发服务器
 接受 服务器文件夹 文件列表 的缓冲区 增大,避免缓冲区溢出 stack smashing  detected
 传参简化
 设置套接字地址重用选项
  程序如下:

    server.c

   #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>

#include <arpa/inet.h>
#include <sys/socket.h>

#define BACKLOG 10

struct message
{
char cmd[10];
char filename[20];
};

void list_file(int ,struct message *);
void get_file(int ,struct message *);
void put_file(int ,struct message *);
void process_cli(int ,struct sockaddr_in );

int main(int argc,char *argv[])
{
int listen_fd,socket_fd;
struct sockaddr_in server_addr,client_addr;
socklen_t client_addrlen;

pid_t pid;

if(argc <3)
{
fprintf(stderr,"Usage : %s ip port\n",argv[0]);
exit(1);
}

if((listen_fd=socket(AF_INET,SOCK_STREAM,0)) <0)
{
perror("failed to create socket");
exit(1);
}
int opt=SO_REUSEADDR;
setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(atoi(argv[2]));
server_addr.sin_addr.s_addr=inet_addr(argv[1]);
//inet.pton(AF_INET,argv[1],&server_addr.sin_addr);

client_addrlen=sizeof(struct sockaddr);

if(bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
{
perror("failed to bind");
exit(1);
}

listen(listen_fd,BACKLOG);

while(1)
{
if((socket_fd=accept(listen_fd,(struct sockaddr *)&client_addr,&client_addrlen)) < 0)
{
perror("failed to accept");
exit(1);
}
if((pid=fork()) >0)
{
close(socket_fd);
continue;
}
else if(pid == 0)
{
close(listen_fd);
process_cli(socket_fd,client_addr);
exit(0);
}
else
{
perror("failed to fork");
exit(1);
}
}
close(listen_fd);
return 0;
}

void process_cli(int socket_fd,struct sockaddr_in client_addr)
{
struct message msg;
memset(&msg,0,sizeof(msg));
recv(socket_fd,&msg,sizeof(msg),0);
printf("cmd : %s\n",msg.cmd);
if(strcmp(msg.cmd,"list") == 0)
list_file(socket_fd,&msg);
else if(strcmp(msg.cmd,"get") == 0 )
get_file(socket_fd,&msg);
else if(strcmp(msg.cmd,"put") == 0)
put_file(socket_fd,&msg);

close(socket_fd);

return ;
}

void list_file(int socket_fd, struct message *msg)
{
DIR *dp;
struct dirent *dirp;
char buf[500];

if((dp =opendir(".")) < 0)
{
perror("failed to open dir");
exit(1);
}
memset(buf,0,sizeof(buf));
while((dirp = readdir(dp)) != NULL)
{
if(strcmp(dirp->d_name,".") == 0 || strcmp(dirp->d_name,"..") == 0)
continue;
strcat(buf,dirp->d_name);
strcat(buf," ");
}

send(socket_fd,buf,strlen(buf) ,0);
closedir(dp);

return ;
}

void get_file(int socket_fd, struct message *msg)
{
int fd;
char buf[1024];
int num=0;
if((fd=open(msg->filename,O_RDONLY)) <0)
{
perror("failed to open file");
exit(1);
}
memset(buf,0,sizeof(buf));
while((num=read(fd,buf,sizeof(buf))) >0)
{
usleep(500);
if(send(socket_fd,buf,num,0) < 0)
{
perror("failed to send date");
exit(1);
}

}
if( num < 0)
{
perror("failed to read ");
exit(1);
}
close(fd);

return ;
}

void put_file(int socket_fd,struct message *msg)
{
int fd;
char buf[1024];
int num=0;
if((fd=open(msg->filename,O_WRONLY | O_CREAT | O_TRUNC ,0666)) < 0 )
{
perror("failed to create file");
exit(1);
}

memset(buf,0,sizeof(buf));
while((num=recv(socket_fd,buf,sizeof(buf),0)) >0)
if( write(fd,buf,num) != num)
{
perror("failed to write");
exit(1);
}
if(num < 0)
{
perror("failed to recv date");
exit(1);
}
close(fd);
return ;
}



client.c
  #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <dirent.h>
#include <fcntl.h>

struct message
{
char cmd[10];
char filename[20];
};

void list_file(struct message ,struct sockaddr_in);
void get_file(struct message ,struct sockaddr_in);
void put_file(struct message ,struct sockaddr_in);

int main(int argc , char *argv[])
{
struct sockaddr_in server_addr;
struct message msg;
char buf[100];
char *arg[10];
int i=0;

if(argc < 3)
{
fprintf(stderr,"Usage : %s ip port\n",argv[0]);
exit(1);
}

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

while(1)
{
memset(buf,0,sizeof(buf));
memset(&msg,0,sizeof(msg));
i=0;

printf("###################################\n");
printf("function:\n");
printf("Input \"list\" can list the file server's files\n");
printf("Input \"get filename\" can download file from server\n");
printf("Input \"put filename\" can upload file to file server\n");
printf("Input \"quit\" can quit the client\n");
printf("####################################\n");
printf(">");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf) - 1 ]=0;

arg[i] = strtok(buf," ");
while(arg[i] != NULL)
arg[++i]= strtok(NULL," ");

strcpy(msg.cmd,arg[0]);
if(strncmp(buf,"quit",4) ==0)
break;
if(strcmp(arg[0],"list") == 0)
{
list_file(msg,server_addr);
}
else if(strcmp(arg[0],"get") == 0)
{
strcpy(msg.filename,arg[1]);
get_file(msg,server_addr);
}
else if(strcmp(arg[0],"put") == 0)
{
strcpy(msg.filename,arg[1]);
put_file(msg,server_addr);
}

}
return 0;
}

void list_file(struct message msg , struct sockaddr_in server_addr)
{
int client_fd;
char buf[500];
if((client_fd=socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("failed to Create socket ");
exit(1);
}

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

if(send(client_fd,&msg,sizeof(msg),0) < 0)
{
perror("failed to send msg");
exit(1);
}

usleep(500);

memset(buf,0,sizeof(buf));
if(recv(client_fd,buf,sizeof(buf),0) < 0 )
{
perror("failed to recv msg");
exit(1);
}
printf("%s\n",buf);
close(client_fd);
return ;
}

void get_file(struct message msg, struct sockaddr_in server_addr)
{
int fd,client_fd;
char buf[1024];
int num=0;

if((client_fd=socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("failed to Create socket ");
exit(1);
}

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

if((fd=open(msg.filename,O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
{
perror("failed to Create file");
exit(1);
}

if(send(client_fd,&msg,sizeof(msg),0) <0 )
{
perror("failed to send msg");
exit(1);
}
memset(buf,0,sizeof(buf));

while((num=recv(client_fd,buf,sizeof(buf),0)) >0)
{
usleep(500);
if(write(fd,buf,num) != num)
{
perror("failed to write");
exit(1);
}
}
if(num <0)
{
perror("failed to recv");
exit(1);
}
printf("Download OK!\n");
close(fd);
close(client_fd);
return ;
}

void put_file(struct message msg, struct sockaddr_in server_addr )
{
int fd,client_fd;
int num=0;
char buf[1024];

if((client_fd=socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("failed to Create socket ");
exit(1);
}

if(connect(client_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
{
perror("failed to connect");
exit(1);
}
if(send(client_fd,&msg,sizeof(msg),0) < 0 )
{
perror("failed to send msg");
exit(1);
}

usleep(500);

if((fd=open(msg.filename,O_RDONLY)) < 0)
{
perror("failed to open file");
exit(1);
}

memset(buf,0,sizeof(buf));
while((num=read(fd,buf,sizeof(buf))) > 0)
if(send(client_fd,buf,num,0) <0)
{
perror("failed to send date");
exit(1);
}
if(num <0)
{
perror("failed to read");
exit(1);
}

printf("UpLoad OK!\n");
close(fd);
close(client_fd);
return ;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息