概述
客户端向服务器发送请求list,查看服务器目录下的文件,
然后,get filename命令将文件下载到本地。
接着,put filename命令将本地文件上传到服务器
最后,quit退出
代码
服务器代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
typedef struct{
int type;
char buf[BUFSIZ];
}MSG;
int do_list(int acceptfd,MSG *msg);
int do_getfile(int acceptfd,MSG *msg);
int do_putfile(int acceptfd,MSG *msg);
int do_client(int acceptfd);
//./client 192.168.203.130 10000
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in serveraddr;
int acceptfd;
pid_t pid;
if(argc != 3){
printf("Usage:%s serverip port.\n",argv[0]);
return -1;
}
//创建套接字
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
perror("socket");
return -1;
}
//绑定套接字
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
if(bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0){
perror("bind");
exit(0);
}
//监听套接字
if(listen(sockfd,5) < 0){
perror("listen");
exit(0);
}
//处理僵尸进程
signal(SIGCHLD,SIG_IGN);
printf("waiting connect.\n");
//主函数
while(1){
//客户连接上服务器,accept为其分配一个新套接字
if((acceptfd = accept(sockfd,NULL,NULL)) < 0){
perror("accept");
return -1;
}
//
printf("connect success.\n");
//创建子进程与客户端进行通信,父进程回到开始继续等待新的客户端连接
if((pid = fork())<0){
perror("fork");
return -1;
}
else if(pid == 0){ //子进程
close(sockfd); //关掉子进程的sockfd
do_client(acceptfd); //处理客户信息模块
}else{ //父进程
close(acceptfd); //关掉父进程的acceptfd
}
}
return 0;
}
//处理客户信息模块
int do_client(int acceptfd){
MSG msg;
while(recv(acceptfd,&msg,sizeof(msg),0) > 0){
switch(msg.type){
case 1:
do_list(acceptfd,&msg);
break;
case 2:
do_getfile(acceptfd,&msg);
break;
case 3:
do_putfile(acceptfd,&msg);
break;
default:
printf("Invalid data msg.\n");
break;
}
}
printf("client exit.\n");
close(acceptfd);
exit(0);
return 0;
}
int do_list(int acceptfd,MSG *msg){
FILE *fp;
system("ls >temp");
if((fp = fopen("temp","r")) == NULL){
perror("fopen");
exit(0);
}
while(fgets(msg->buf,sizeof(MSG),fp) != NULL){
send(acceptfd,msg,sizeof(MSG),0);
}
fclose(fp);
msg->buf[0] = '\0';
send(acceptfd,msg,sizeof(MSG),0);
system("rm temp");
return 0;
}
int do_getfile(int acceptfd,MSG *msg){
FILE *fp;
// printf("%s--%d\n",msg->buf,strlen(msg->buf));
if((fp = fopen(msg->buf,"r")) == NULL){
perror("fopen");
exit(1);
}
while(fgets(msg->buf,sizeof(MSG),fp) != NULL){
send(acceptfd,msg,sizeof(MSG),0);
// printf("%s\n",msg->buf);
}
fclose(fp);
strcpy(msg->buf,"finished");
send(acceptfd,msg,sizeof(MSG),0);
return 0;
}
int do_putfile(int acceptfd,MSG *msg){
FILE *fp;
fp = fopen(msg->buf,"w+");
while(1){
recv(acceptfd,msg,sizeof(MSG),0);
if(msg->buf[0] == '\0'){
break;
}
fputs(msg->buf,fp);
}
fclose(fp);
return 0;
}
客户端代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
typedef struct{
int type;
char buf[BUFSIZ];
}MSG;
int do_list(int sockfd,MSG *msg);
int do_getfile(int sockfd,MSG *msg);
int do_putfile(int sockfd,MSG *msg);
//./client 192.168.203.130 10000
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in serveraddr;
MSG msg;
if(argc != 3){
printf("Usage:%s serverip port.\n",argv[0]);
return -1;
}
//创建流式套接字
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
perror("socket");
return -1;
}
//连接服务器
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0){
perror("fail to connect");
return -1;
}
char s[32] = {0} ;
//主函数
while(1){
//一级交互界面
printf("**************************\n");
printf("***请输入 help 查看选项***\n");
printf("**************************\n");
printf("Input your choice:>>>");
scanf("%s",s);
getchar();
if(strncmp(s,"help",5) == 0){
goto next;
}else{
printf("Input error!!!\n");
}
}
next:
while(1){
int n = 0;
//二级交互界面
printf("********************************************************\n");
printf("********输入/功能***************************************\n");
printf("********list:查看服务器所在目录的所有文件***************\n");
printf("********get filename:下载服务器目录的文件***************\n");
printf("********put filename:上传服务器目录的文件***************\n");
printf("********quit:关闭客户端*********************************\n");
printf("********************************************************\n");
printf("Input your choice:>>>");
fgets(s,32,stdin);
int len = strlen(s);
s[len-1] = '\0';
strcpy(msg.buf,s);
// printf("%s\n",s);
if(strncmp(s,"list",5) == 0){
n = 1;
}else if(strncmp(s,"get ",3) == 0){
strtok(msg.buf," ");
strcpy(msg.buf,strtok(NULL," "));
// printf("%s\n",msg.buf);
n = 2;
}else if(strncmp(s,"put ",3) == 0){
strtok(msg.buf," ");
strcpy(msg.buf,strtok(NULL," "));
n = 3;
}else if(strncmp(s,"quit",5) == 0){
n = 4;
}else{
printf("Input error.please input again!!\n");
goto next;
}
switch(n){
case 1:
do_list(sockfd,&msg);
break;
case 2:
do_getfile(sockfd,&msg);
break;
case 3:
do_putfile(sockfd,&msg);
break;
default:
close(sockfd);
exit(0);
break;
}
}
return 0;
}
int do_list(int sockfd,MSG* msg){
msg->type = 1;
send(sockfd,msg,sizeof(MSG),0);
while(1){
if(recv(sockfd,msg,sizeof(MSG),0) > 0){
if((strncmp(msg->buf,"temp",4) != 0)&&(strncmp(msg->buf,"feng",4) != 0)){
printf("%s",msg->buf);
}
}
if(msg->buf[0] == '\0'){
printf("List finish!!!\n");
break;
}
}
return 0;
}
int do_getfile(int sockfd,MSG * msg){
FILE *fp;
// printf("%s\n",msg->buf); msg->buf === filename
fp = fopen(msg->buf,"w");
msg->type = 2;
send(sockfd,msg,sizeof(MSG),0);
while(1){
recv(sockfd,msg,sizeof(MSG),0);
if(strncmp(msg->buf,"finished",8) == 0){
printf("get file success!!!\n");
break;
}
fputs(msg->buf,fp);
}
fclose(fp);
return 0;
}
int do_putfile(int sockfd,MSG *msg){
FILE *fp;
if((fp = fopen(msg->buf,"r")) == NULL){
perror("fopen");
exit(0);
}
msg->type = 3;
printf("%s\n",msg->buf);
send(sockfd,msg,sizeof(MSG),0);
while(fgets(msg->buf,sizeof(MSG),fp) != NULL){
send(sockfd,msg,sizeof(MSG),0);
}
fclose(fp);
msg->buf[0] = '\0';
send(sockfd,msg,sizeof(MSG),0);
printf("put file success!!!\n");
return 0;
}
效果展示
客户端窗口:
zgy@zgy-virtual-machine:~/level8/zuoye/2/feng$ ls
client1 hello.c server1.c
zgy@zgy-virtual-machine:~/level8/zuoye/2/feng$ ./client1 192.168.203.130 5001
**************************
***请输入 help 查看选项***
**************************
Input your choice:>>>help
********************************************************
********输入/功能***************************************
********list:查看服务器所在目录的所有文件***************
********get filename:下载服务器目录的文件***************
********put filename:上传服务器目录的文件***************
********quit:关闭客户端*********************************
********************************************************
Input your choice:>>>list
client1.c
he.c
Makefile
server1
server1.c
List finish!!!
********************************************************
********输入/功能***************************************
********list:查看服务器所在目录的所有文件***************
********get filename:下载服务器目录的文件***************
********put filename:上传服务器目录的文件***************
********quit:关闭客户端*********************************
********************************************************
Input your choice:>>>get he.c
get file success!!!
********************************************************
********输入/功能***************************************
********list:查看服务器所在目录的所有文件***************
********get filename:下载服务器目录的文件***************
********put filename:上传服务器目录的文件***************
********quit:关闭客户端*********************************
********************************************************
Input your choice:>>>put hello.c
hello.c
put file success!!!
********************************************************
********输入/功能***************************************
********list:查看服务器所在目录的所有文件***************
********get filename:下载服务器目录的文件***************
********put filename:上传服务器目录的文件***************
********quit:关闭客户端*********************************
********************************************************
Input your choice:>>>quit
zgy@zgy-virtual-machine:~/level8/zuoye/2/feng$ ls
client1 he.c hello.c server1.c
zgy@zgy-virtual-machine:~/level8/zuoye/2/feng$ vim he.c
zgy@zgy-virtual-machine:~/level8/zuoye/2/feng$ cat he.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("he\n");
return 0;
}
服务器窗口:
zgy@zgy-virtual-machine:~/level8/zuoye/2$ ls
client1.c feng he.c Makefile server1 server1.c
zgy@zgy-virtual-machine:~/level8/zuoye/2$ ./server1 192.168.203.130 5001
waiting connect.
connect success.
client exit.
^C
zgy@zgy-virtual-machine:~/level8/zuoye/2$ ls
client1.c feng he.c hello.c Makefile server1 server1.c
zgy@zgy-virtual-machine:~/level8/zuoye/2$ cat hello.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("where there is a will,there is a way.");
return 0;
}
zgy@zgy-virtual-machine:~/level8/zuoye/2$
可以看到文件he.c下载下来了。文件hello.c上传上去了。
(需要注意的是,只能传递小字节数文件,并且程序没有出错判断)