项目功能
- 实现客户端远程从服务器端获取文件(get xxx)
- 实现客户端上传文件到服务器端(put xxx)
- 对服务器当前目录的基本操作(ls,cd,pwd)
- 对客户端当前目录的操作(lls,lcd)
> 1,2是项目的主要功能
> 3,4是为了方便1,2功能de
项目实现
在Linux系统下基于socket编程实现,用到以下主要函数:
服务器端
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include<string.h>
#include"config.h"
#include <sys/stat.h>
#include <fcntl.h>
int get_cmd(char cmd[128])
{
if(!strcmp("ls",cmd)) return LS;
if(!strcmp("pwd",cmd)) return PWD;
if(!strcmp("quit",cmd)) return QUIT;
if(strstr(cmd,"cd")!=NULL) return CD;
if(strstr(cmd,"get")!=NULL) return GET;
if(strstr(cmd,"put")!=NULL) return PUT;
return -1;
}
char *get_dir(char *cmd)
{
char *p;
p=strtok(cmd," ");
p=strtok(NULL," ");
return p;
}
void handler_msg(int fd,struct Msg msg)
{
int ret;
int fdfile;
FILE *fp;
char readbuff[1024]={0};
char *p=NULL;
char *file=NULL;
printf("->%s\n",msg.cmd);
ret = get_cmd(msg.cmd);
// printf("the ret :%d\n",ret);
switch(ret){
case LS:
case PWD:
msg.type = 11;
fp=popen(msg.cmd,"r");
if(fp == NULL){
printf("popen error!\n");
exit(-1);
}
memset(msg.data,0,sizeof(msg.data));
fread(msg.data,sizeof(msg.data),1,fp);
// printf("fread:\n%s\n",msg.data);
write(fd,&msg,sizeof(msg));
pclose(fp);
break;
case CD:
p = get_dir(msg.cmd);
// printf("dir:%s\n",p);
chdir(p);
break;
case GET:
msg.type = IFFILE;
file = get_dir(msg.cmd);
// printf("GET need file:%s\n",file);
if(access(file,F_OK)==-1){
strcpy(msg.data,"No this file");
write(fd,&msg,sizeof(msg));
}else{
fdfile=open(file,O_RDWR);
if(read(fdfile,readbuff,sizeof(readbuff))==0){
printf("GET:read error\n");
}
close(fdfile);
strcpy(msg.data,readbuff);
write(fd,&msg,sizeof(msg));
}
break;
case PUT:
// printf("PUT:msg.data%s\n",msg.data);
// printf("PUT:dir:%s\n",get_dir(msg.cmd));
fdfile=open(get_dir(msg.cmd),O_RDWR|O_CREAT,0666);
if(fdfile == -1){
printf("PUT:open failed\n");
perror("open");
}
write(fdfile,msg.data,sizeof(msg.data));
close(fdfile);
system("ls");
break;
case QUIT:
printf("client is quit\n");
close(fd);
exit(-1);
printf("also quit!");
break;
}
}
int main(int argc,char **argv)
{
int s_fd;
int c_fd;
int n_read;
struct Msg msg;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset(&s_addr,0,sizeof(struct sockaddr_in));
memset(&c_addr,0,sizeof(struct sockaddr_in));
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd==-1){
perror("socket");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr));
listen(s_fd,10);
int len = sizeof(struct sockaddr_in);
while(1){
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&len);
if(c_fd == -1){
perror("accept:");
exit(-1);
}
printf("get connect%s\n",inet_ntoa(c_addr.sin_addr));
if(fork() == 0){
while(1){
memset(msg.cmd,0,sizeof(msg.cmd));
n_read = read(c_fd,&msg,sizeof(msg));
if(n_read == 0){
printf("client is wrong!\n");
break;
}else if(n_read > 0){
handler_msg(c_fd,msg);
}
}
}
}
close(s_fd);
close(c_fd);
return 0;
}
客户端
#include<stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<stdlib.h>
#include <unistd.h>
#include<string.h>
#include"config.h"
#include <sys/stat.h>
#include <fcntl.h>
//int socket(int domain, int type, int protocol);
// int bind(int sockfd, const struct sockaddr *addr,
// socklen_t addrlen);
//int listen(int sockfd, int backlog);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int get_cmd(char cmd[128])
{
if(!strcmp("ls",cmd)) return LS;
if(!strcmp("pwd",cmd)) return PWD;
if(!strcmp("quit",cmd)) return QUIT;
if(!strcmp("lls",cmd)) return LLS;
if(strstr(cmd,"lcd")!=NULL) return LCD;
if(strstr(cmd,"cd")!=NULL) return CD;
if(strstr(cmd,"get")!=NULL) return GET;
if(strstr(cmd,"put")!=NULL) return PUT;
return -1;
}
char *get_dir(char *cmd)
{
char *p;
p=strtok(cmd," ");
p=strtok(NULL," ");
return p;
}
int handler_client(int fd,struct Msg msg)
{
int ret;
int fdfile;
char*file;
char *p=NULL;
char readbuff[1024]={0};
struct Msg put;
strcpy(put.cmd,msg.cmd);
ret = get_cmd(msg.cmd);
switch(ret){
case LLS:
puts("---------------------\n");
system("ls");
break;
case LCD:
p = get_dir(msg.cmd);
chdir(p);
break;
case LS:
case PWD:
case CD:
// printf("%s\n",msg.cmd);
write(fd,&msg,sizeof(msg));
break;
case GET:
write(fd,&msg,sizeof(msg));
break;
case PUT:
file = get_dir(msg.cmd);
fdfile = open(file,O_RDWR);
read(fdfile,readbuff,sizeof(readbuff));
close(fdfile);
memset(put.data,0,sizeof(put.data));
strcpy(put.data,readbuff);
// printf("the put.cmd:%s\n",put.cmd);
// printf("the put.data:%s\n",put.data);
write(fd,&put,sizeof(put));
break;
case QUIT:
// strcpy(msg.data,"client is quit");
write(fd,&msg,sizeof(msg));
close(fd);
exit(-1);
break;
}
return ret;
}
void handler_server_msg(int fd,struct Msg msg)
{
int n_read;
int file;
char *p=NULL;
struct Msg getmsg;
// printf("the type:%d\n",getmsg.type);
n_read=read(fd,&getmsg,sizeof(getmsg));
if(n_read == 0){
printf("client is not ok\n");
exit(-1);
}else if(getmsg.type == IFFILE){
p = get_dir(msg.cmd);
file = open(p,O_RDWR|O_CREAT,0666);
write(file,getmsg.data,sizeof(getmsg.data));
close(file);
// putchar('>');
fflush(stdout);
}else{
printf("------------------------\n");
printf("\n%s\n",getmsg.data);
printf("------------------------\n");
fflush(stdout);
}
}
int main(int argc,char **argv)
{
int c_fd;
int n_read;
struct Msg msg;
struct sockaddr_in c_addr;
if(argc != 3){
printf("param is not good\n");
exit(-1);
}
memset(&c_addr,0,sizeof(struct sockaddr_in));
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1){
perror("socket");
exit(-1);
}
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&c_addr.sin_addr);
if(connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr)) == -1){
perror("connect");
exit(-1);
}
printf("connect success ip:%s\n",inet_ntoa(c_addr.sin_addr));
while(1){
if(memset(msg.cmd,0,sizeof(msg.cmd))==NULL){
printf("memset error\n");
exit(0);
}
printf("> ");
gets(msg.cmd);
// printf("cmd:%s\n",msg.cmd);
int ret =handler_client(c_fd,msg);
// printf("return ret:%d\n",ret);
if(ret<DOFILE){
fflush(stdout);
continue;
}else if(ret == -1){
printf("input is not ok\n");
fflush(stdout);
continue;
}
handler_server_msg(c_fd,msg);
}
close(c_fd);
return 0;
}
config.h
#define QUIT 0
#define LCD 1
#define CD 2
#define LLS 3
#define PUT 4
#define DOFILE 5
#define PWD 6
#define GET 7
#define LS 8
#define IFFILE 9
struct Msg{
int type;
char cmd[128];
char data[1024];
};