服务器端的实现:
#include <sys/types.h>
#include <sys/socket.h>
#include<netinet/in.h>//sockaddr_in等结构的定义
#include<netdb.h>//addrinfo等结构的定义
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define TRUE 1
#define LISTEN_PORT 3499
#define dataLen 1024
char currentDirPath[200];
char currentDirName[30];
char help[]="get
get a file from server\n\
put
upload afile to server\n\
pwd
display
the current directory of server\n\
dir
displaythe files in the current directory of server\n\
cd
change thedirectory of server\n\
?
display thewhole command which equals 'help'\n\
quit
return\n";
char *getDirName(char *dirPathName);
void cmd_pwd(int sock);
void cmd_dir(int sock);
void cmd_cd(int sock,char *dirName);
void cmd_cdback(int sock);
void cmd_help(int sock);
void cmd_get(int sock,char*fileName);
void cmd_put(int sock,char *fileName);
int main(int argc,char *argv[])
{
int sock,sockmsg, length,lengthmsg;
char client_cmd[10] ,cmd_arg[20];
struct sockaddr_inserver;
struct sockaddr_inservermsg;
int datasock,msgsock;
pid_t child;
// intdatasock;
//data socket
int rval;
sock=socket(AF_INET,SOCK_STREAM,0);//创建流式套接字
sockmsg=socket(AF_INET,SOCK_STREAM,0);
if(sock<0||sockmsg<0)
{
perror("opening stream socket");
exit(1);
}
server.sin_family=AF_INET;//AF_INET针对internet,另一种形式AF_UNIX只能够用于单一的Unix系统进程通信(主机通信协议)
server.sin_addr.s_addr=INADDR_ANY;//表示可以和任何主机通信
server.sin_port=htons(LISTEN_PORT);//htons将短整形数据转换位网络字节顺序
servermsg.sin_family=AF_INET;
servermsg.sin_addr.s_addr=INADDR_ANY;
servermsg.sin_port=htons(LISTEN_PORT+1);
if (bind(sock,(struct sockaddr*)&server,sizeofserver)<0||bind(sockmsg,(struct sockaddr*)&servermsg,sizeofservermsg)<0)//将本地端口与socket返回的文件描述符绑定在一起
{
perror("binding stream socket");
exit(1);
}
length=sizeof server;
lengthmsg=sizeofservermsg;
if (getsockname(sock,(structsockaddr*)&server,&length)<0||getsockname(sockmsg,(structsockaddr*)&servermsg,&lengthmsg)<0)//用于得套接口的名字
{
perror("getting socket name");
exit(1);
}
printf("Socket port #%d
%d\n",ntohs(server.sin_port),ntohs(servermsg.sin_port));
memset(currentDirPath,0,sizeof(currentDirPath));//将currentDirpath置零
getcwd(currentDirPath,sizeof(currentDirPath));//得到当前路径,保存在currentDirPath中
listen(sock,2);//监听,允许最大监听数位2,将绑定的套接字变成监听套接字
listen(sockmsg,2);
do
{
datasock = accept(sock,(structsockaddr*)0,(int*)0);//接受请求
msgsock =accept(sockmsg,(struct sockaddr*)0,(int*)0);
if (datasock ==-1||msgsock==-1)
perror("accept");
else
{
if((child=fork())==-1)//创建子进程
{
printf("Fork Error!\n");
}
//The child process
if(child==0)
{
printf("connection accepted! new clientcomming\n");
loop:
memset(client_cmd,0,sizeof(client_cmd));
rval=0;
rval=read(msgsock,client_cmd,sizeof(client_cmd));//从msgsock中读取数据到client_cmd
if(rval<0)
{
perror("reading command failed\n");
}
else if(rval==0)
{
printf("connection closed.\n");
close(datasock);//关闭套接字
close(msgsock);
}
else
{
if(strcmp(client_cmd,"pwd")==0)
{
printf("cmmand pwd\n");
cmd_pwd(datasock);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"dir")==0)
{
printf("command dir\n");
cmd_dir(datasock);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"cd")==0)
{
printf("command cd\n");
//read the argument
memset(cmd_arg,0,sizeof(cmd_arg));
read(msgsock,cmd_arg,sizeof(cmd_arg));
cmd_cd(datasock,cmd_arg);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"cd..")==0)
{
printf("command cd..\n");
cmd_cdback(datasock);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"get")==0)
{
printf("command get\n");
memset(cmd_arg,0,sizeof(cmd_arg));
read(msgsock,cmd_arg,sizeof(cmd_arg));
cmd_get(datasock,cmd_arg);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"put")==0)
{
printf("command put\n");
memset(cmd_arg,0,sizeof(cmd_arg));
read(msgsock,cmd_arg,sizeof(cmd_arg));
cmd_put(datasock,cmd_arg);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"?")==0)
{
printf("command ?\n");
cmd_help(datasock);
printf("done\n\n");
goto loop;
}
else if(strcmp(client_cmd,"quit")==0)
{
printf("quit\n");
goto endchild;
}
else
{
printf("bad request!\n");
goto loop;
}
}
endchild:
printf("connection closed.\n");
close(datasock);
close(msgsock);
exit(0);
}
}
}while(TRUE);
exit(0);
}
//pwd command
void cmd_pwd(int sock)
{
intlen;
memset(currentDirPath,0,sizeof(currentDirPath));
getcwd(currentDirPath,sizeof(currentDirPath));
char*savePointer=getDirName(currentDirPath);
strcpy(currentDirName,savePointer);
len=strlen(currentDirName)+1;
write(sock,currentDirName,len);
}
//dir command
void cmd_dir(int sock)
{
DIR *pdir;//目录结构
charfileName[30];
charfileInfo[50];
int i,fcounts=0, len;
structdirent *pent;//目录的结构体属性
intfd;
struct statfileSta;//文件属性
charfilePath[200];
pdir=opendir(currentDirPath);//打开目录
pent=readdir(pdir);//读取目录
while(pent!=NULL)
{
fcounts++;//计算文件个数
pent=readdir(pdir);
}
write(sock,&fcounts,sizeof(int));//将文件个数写入sock
closedir(pdir);//关闭目录
if(fcounts<=0)
{
return;
}
else
{
pdir=opendir(currentDirPath);
for(i=0;i<fcounts;i++)
{
pent=readdir(pdir);
memset(fileName,0,30);
memset(fileInfo,0,sizeof(fileInfo));
strcpy(fileName,pent->d_name);
//check the file is a directory or a file
memset(filePath,0,sizeof(filePath));
strcpy(filePath,currentDirPath);
strcat(filePath,"/");//链接两个字符串
strcat(filePath,fileName);
fd=open(filePath,O_RDONLY, S_IREAD);
fstat(fd,&fileSta);//用来读取打开的文件的属性,stat用来读取没有打开的文件的属性
if(S_ISDIR(fileSta.st_mode))//判断文件是否为目录
{
strcat(fileInfo,"dir\t");
strcat(fileInfo,fileName);
}
else
{
strcat(fileInfo,"file\t");
strcat(fileInfo,fileName);
}
write(sock,fileInfo,sizeof(fileInfo));
}
closedir(pdir);
}
}
//command cd
void cmd_cd(int sock,char *dirName)
{
DIR*pdir;
structdirent *pent;
charfilename[30];
inti,fcounts=0;
intflag=0;
pdir=opendir(currentDirPath);
pent=readdir(pdir);
while(pent!=NULL)
{
fcounts++;
pent=readdir(pdir);
}
closedir(pdir);
if(fcounts<=0)
{
return;
}
else
{
pdir=opendir(currentDirPath);
for(i=0;i<fcounts;i++)
{
pent=readdir(pdir);
if(strcmp(pent->d_name,dirName)==0)
{
strcat(currentDirPath,"/");
strcat(currentDirPath,dirName);
flag=1;
break;
}
}
if(flag==1)
{
write(sock,currentDirPath,sizeof(currentDirPath));
}
closedir(pdir);
}
}
//command cd..
void cmd_cdback(int sock)
{
intlen;
int i,record;
len=strlen(currentDirPath);
for(i=len-1;i>=0;i--)
{
if(currentDirPath[i]=='/')
{
currentDirPath[i]='\0';
break;
}
currentDirPath[i]='\0';
}
}
//command ?
void cmd_help(int sock)
{
intlen=strlen(help)+1;
write(sock,help,len);
}
//command get
void cmd_get(int sock,char*fileName)
{
intfd;
struct statfileSta;
longfileSize;
charfilePath[200], buf[dataLen];
memset(filePath,0,sizeof(filePath));
strcpy(filePath,currentDirPath);
strcat(filePath,"/");
strcat(filePath,fileName);
fd=open(filePath,O_RDONLY, S_IREAD);
if(fd!=-1)
{
fstat(fd,&fileSta);
fileSize=(long) fileSta.st_size;//?
write(sock,&fileSize,sizeof(long));
memset(buf,0,dataLen);
while(fileSize>dataLen)
{
read(fd,buf,dataLen);
write(sock,buf,dataLen);
fileSize=fileSize-dataLen;
}
read(fd,buf,fileSize);
write(sock,buf,fileSize);
close(fd);
printf("transfer completed\n");
}
else
{
printf("open file %s failed\n",filePath);
}
}
//command put
void cmd_put(int sock,char *fileName)
{
intfd;
longfileSize;
charfilePath[200], buf[dataLen];
strcpy(filePath,currentDirPath);
strcat(filePath,"/");
strcat(filePath,fileName);
fd=open(filePath,O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
if(fd!=-1)
{
memset(buf,0,dataLen);
read(sock,&fileSize,sizeof(long));
while(fileSize>dataLen)
{
read(sock,buf,dataLen);
write(fd,buf,dataLen);
fileSize=fileSize-dataLen;
}
read(sock,buf,fileSize);
write(fd,buf,fileSize);
close(fd);
printf("transfer completed\n");
}
else
{
printf("open file %s failed\n",filePath);
}
}
//get the last string after the last char '/'
char *getDirName(char *dirPathName)
{
int i, pos,len;
char*dirName;
if(dirPathName==NULL)
{
printf("directory absoultly path isnull!\n");
return NULL;
}
len=strlen(dirPathName);
for(i=len-1;i>=0;i--)
{
if(dirPathName[i]=='/')
{
pos=i;
break;
}
}
dirName=(char *)malloc(len-pos+1);
for(i=pos+1;i<len;i++)
{
dirName[i-pos-1]=dirPathName[i];
}
returndirName;
}
客户端实现:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#define TRUE 1
#define dataLen 1024
char user_cmd[10],cmd_arg[20];
char buf[dataLen];
void cmd_pwd(int sock,int sockmsg);
void cmd_dir(int sock,int sockmsg);
void cmd_cd(int sock,int sockmsg,char *dirName);
void cmd_cdback(int sock,int sockmsg);
void cmd_help(int sock,int sockmsg);
void cmd_get(int sock,int sockmsg,char *fileName);
void cmd_put(int sock,int sockmsg,char *fileName);
void cmd_quit(int sock,int sockmsg);
int main(int argc,char *argv[])
{
int cmd_len,arg_len;
int sock, sockmsg;
struct sockaddr_in server, servermsg;
struct hostent *hp;
sock=socket(AF_INET,SOCK_STREAM,0);
sockmsg=socket(AF_INET,SOCK_STREAM,0);
if(sock<0||sockmsg<0)
{
perror("opening stream socket");
exit(1);
}
hp = gethostbyname(argv[1]);
if (hp==0)
{
fprintf(stderr,"%s:unknown host\n",argv[1]);
exit(2);
}
server.sin_family=AF_INET;
server.sin_port=htons(atoi(argv[2]));
memcpy((char*)&server.sin_addr,(char*)hp->h_addr,hp->h_length);
servermsg.sin_family=AF_INET;
servermsg.sin_port=htons(atoi(argv[2])+1);
memcpy((char*)&servermsg.sin_addr,(char*)hp->h_addr,hp->h_length);
if (connect(sock,(struct sockaddr*)&server,sizeofserver)<0||connect(sockmsg,(struct sockaddr*)&servermsg,sizeofservermsg)<0)
{
perror("connecting stream socket");
exit(1);
}
//Get command from command line and do just theaction
while(TRUE)
{
memset(user_cmd,0,10);
memset(cmd_arg,0,20);
//First getthe input character by user
printf("command: ");
scanf("%s",user_cmd);
cmd_len=strlen(user_cmd);
//Then getthe command character and the argument
if(strcmp(user_cmd,"quit")==0)
//command"quit"
{
cmd_quit(sock,sockmsg);
close(sockmsg);
close(sock);
printf("connection closed\n\n");
exit(0);
}
elseif(strcmp(user_cmd,"?")==0)
//command"?"
{
cmd_help(sock,sockmsg);
}
elseif(strcmp(user_cmd,"pwd")==0)
//command"pwd"
{
cmd_pwd(sock,sockmsg);
}
elseif(strcmp(user_cmd,"dir")==0)
//command"dir"
{
cmd_dir(sock,sockmsg);
}
elseif(strcmp(user_cmd,"cd")==0)
//commad "cd"
{
//inputcommand argument
scanf("%s",cmd_arg);
cmd_cd(sock,sockmsg,cmd_arg);
}
elseif(strcmp(user_cmd,"cd..")==0)
{
cmd_cdback(sock,sockmsg);
}
elseif(strcmp(user_cmd,"get")==0)
//command "get"
{
//inputcommand argument
scanf("%s",cmd_arg);
cmd_get(sock,sockmsg,cmd_arg);
}
elseif(strcmp(user_cmd,"put")==0)
//command "put"
{
//inputcommand argument
scanf("%s",cmd_arg);
cmd_put(sock,sockmsg,cmd_arg);
}
else
{
printf("badcommand!\n");
}
}
}
//command pwd
void cmd_pwd(int sock,int sockmsg)
{
//intnumRead;
chardirName[30];
write(sockmsg,user_cmd,sizeof(user_cmd));
read(sock,dirName,30);
printf("%s\n",dirName);
}
//command dir
void cmd_dir(int sock, int sockmsg)
{
int i,fileNum=0;
charfileInfo[50];
write(sockmsg,user_cmd,sizeof(user_cmd));
read(sock,&fileNum,sizeof(int));
printf("--------------------------------------------------------\n");
printf("filenumber : %d\n",fileNum);
if(fileNum>0)
{
for(i=0;i<fileNum;i++)
{
memset(fileInfo,0,sizeof(fileInfo));
read(sock,fileInfo,sizeof(fileInfo));
printf("%s\n",fileInfo);
}
printf("--------------------------------------------------------\n");
}
elseif(fileNum==0)
{
printf("directory of server point is empty.\n");
return;
}
else
{
printf("error in command 'dir'\n");
return;
}
}
//command cd
void cmd_cd(int sock,int sockmsg,char *dirName)
{
charcurrentDirPath[200];
write(sockmsg,user_cmd,sizeof(user_cmd));
write(sockmsg,cmd_arg,sizeof(cmd_arg));
read(sock,currentDirPath,sizeof(currentDirPath));
printf("nowin directory : %s\n",currentDirPath);
}
//command cd..
void cmd_cdback(int sock,int sockmsg)
{
write(sockmsg,user_cmd,sizeof(user_cmd));
}
//command quit
void cmd_quit(int sock,int sockmsg)
{
write(sockmsg,user_cmd,sizeof(user_cmd));
}
//command help
void cmd_help(int sock, int sockmsg)
{
charhelp[300];
write(sockmsg,user_cmd,sizeof(user_cmd));
read(sock,help,300);
printf("%s\n",help);
}
//command get
void cmd_get(int sock,int sockmsg,char *fileName)
{
intfd;
longfileSize;
charlocalFilePath[200];
write(sockmsg,user_cmd,sizeof(user_cmd));
write(sockmsg,cmd_arg,sizeof(cmd_arg));
printf("%s\n%s\n",user_cmd,cmd_arg);
memset(localFilePath,0,sizeof(localFilePath));
getcwd(localFilePath,sizeof(localFilePath));
strcat(localFilePath,"/");
strcat(localFilePath,fileName);
fd=open(localFilePath,O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
if(fd!=-1)
{
memset(buf,0,dataLen);
read(sock,&fileSize,sizeof(long));
while(fileSize>dataLen)
{
read(sock,buf,dataLen);
write(fd,buf,dataLen);
fileSize=fileSize-dataLen;
}
read(sock,buf,fileSize);
write(fd,buf,fileSize);
close(fd);
printf("download completed\n");
}
else
{
printf("openfile %s failed\n",localFilePath);
}
}
//command put
void cmd_put(int sock,int sockmsg,char* fileName)
{
write(sockmsg,user_cmd,sizeof(user_cmd));
write(sockmsg,cmd_arg,sizeof(cmd_arg));
intfd;
longfileSize;
intnumRead;
charfilePath[200];
struct statfileSta;
memset(filePath,0,sizeof(filePath));
getcwd(filePath,sizeof(filePath));
strcat(filePath,"/");
strcat(filePath,fileName);
fd=open(filePath,O_RDONLY, S_IREAD);
if(fd!=-1)
{
fstat(fd,&fileSta);
fileSize=(long) fileSta.st_size;
write(sock,&fileSize,sizeof(long));
memset(buf,0,dataLen);
while(fileSize>dataLen)
{
read(fd,buf,dataLen);
write(sock,buf,dataLen);
fileSize=fileSize-dataLen;
}
read(fd,buf,fileSize);
write(sock,buf,fileSize);
close(fd);
printf("upload completed\n");
}
else
{
printf("openfile %s failed\n",filePath);
}
}
#include <sys/types.h>
#include <sys/socket.h>
#include<netinet/in.h>//sockaddr_in等结构的定义
#include<netdb.h>//addrinfo等结构的定义
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define TRUE 1
#define LISTEN_PORT 3499
#define dataLen 1024
char currentDirPath[200];
char currentDirName[30];
char help[]="get
put
pwd
dir
cd
?
quit
char *getDirName(char *dirPathName);
void cmd_pwd(int sock);
void cmd_dir(int sock);
void cmd_cd(int sock,char *dirName);
void cmd_cdback(int sock);
void cmd_help(int sock);
void cmd_get(int sock,char*fileName);
void cmd_put(int sock,char *fileName);
int main(int argc,char *argv[])
{
loop:
endchild:
}
//pwd command
void cmd_pwd(int sock)
{
}
//dir command
void cmd_dir(int sock)
{
}
//command cd
void cmd_cd(int sock,char *dirName)
{
}
//command cd..
void cmd_cdback(int sock)
{
}
//command ?
void cmd_help(int sock)
{
}
//command get
void cmd_get(int sock,char*fileName)
{
}
//command put
void cmd_put(int sock,char *fileName)
{
}
//get the last string after the last char '/'
char *getDirName(char *dirPathName)
{
}
客户端实现:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#define TRUE 1
#define dataLen 1024
char user_cmd[10],cmd_arg[20];
char buf[dataLen];
void cmd_pwd(int sock,int sockmsg);
void cmd_dir(int sock,int sockmsg);
void cmd_cd(int sock,int sockmsg,char *dirName);
void cmd_cdback(int sock,int sockmsg);
void cmd_help(int sock,int sockmsg);
void cmd_get(int sock,int sockmsg,char *fileName);
void cmd_put(int sock,int sockmsg,char *fileName);
void cmd_quit(int sock,int sockmsg);
int main(int argc,char *argv[])
{
}
//command pwd
void cmd_pwd(int sock,int sockmsg)
{
}
//command dir
void cmd_dir(int sock, int sockmsg)
{
}
//command cd
void cmd_cd(int sock,int sockmsg,char *dirName)
{
}
//command cd..
void cmd_cdback(int sock,int sockmsg)
{
}
//command quit
void cmd_quit(int sock,int sockmsg)
{
}
//command help
void cmd_help(int sock, int sockmsg)
{
}
//command get
void cmd_get(int sock,int sockmsg,char *fileName)
{
}
//command put
void cmd_put(int sock,int sockmsg,char* fileName)
{
}