ftp服务器的简单实现——服务器端
Posted 众生皆苦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ftp服务器的简单实现——服务器端相关的知识,希望对你有一定的参考价值。
服务器端的代码:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <unistd.h> #include <stdio.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 a file to server\n" "pwd display the current directory of server\n" "cd change the directory of server\n" "? display the whole 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_in server; struct sockaddr_in servermsg; int datasock, msgsock; pid_t child; //int datasock; //data socket int rval; sock = socket(AF_INET, SOCK_STREAM, 0); sockmsg = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0 || sockmsg < 0) { perror("opeing stream socket"); exit(0); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(LISTEN_PORT); 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, sizeof(server)) <0 || bind(sockmsg, (struct sockaddr*)&servermsg, sizeof(servermsg))<0 ) { perror("binding stream socket"); exit(1); } length = sizeof(server); lengthmsg = sizeof(servermsg); if(getsockname(sock, (struct sockaddr *)&server, &length) < 0 || getsockname(sockmsg, (struct sockaddr *)&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)); getcwd(currentDirPath, sizeof(currentDirPath)); listen(sock, 2); listen(sockmsg, 2); do { datasock = accept(sock, (struct sockaddr *)0, (int *)0); msgsock = accept(sockmsg, (struct sockaddr*)0, (int *)0); if(-1 == datasock || -1 == msgsock) { perror("accept"); } else { if(-1 == (child = fork())) { printf("Fork Error!\n"); } //The child process if(0 == child) { printf("connection accepted! new client comming\n"); loop: memset(client_cmd, 0, sizeof(client_cmd)); rval = 0; rval = read(msgsock, client_cmd, sizeof(client_cmd)); if(rval < 0) { perror("reading command failed\n"); } else if(0 == rval) { printf("connection closed.\n"); close(datasock); close(msgsock); } else { if(strcmp(client_cmd, "pwd") == 0) { printf("command 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("\n\n"); goto loop; } else if(strcmp(client_cmd, "cd") == 0) { printf("command cd\n"); 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 get\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) { int len; memset(currentDirPath, 0, sizeof(currentDirPath)); getcwd(currentDirPath, sizeof(currentDirPath)); char *savePointer = getDirName(currentDirPath); printf("currentDirPath is %s", currentDirPath); strcpy(currentDirName, savePointer); printf("currentDirName is %s\n", currentDirName); len = strlen(currentDirName)+1; printf("len is %d\n", len); write(sock, currentDirName, len); } //dir command void cmd_dir(int sock) { DIR *pdir; char fileName[30]; char fileInfo[50]; int i, fcounts = 0, len; struct dirent *pent; int fd; struct stat fileSta; char filePath[200]; pdir = opendir(currentDirPath); pent = readdir(pdir); while(pent!=NULL) { fcounts++; pent = readdir(pdir); } write(sock, &fcounts, sizeof(int)); 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); 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); } } void cmd_cd(int sock, char *dirName) { DIR *pdir; struct dirent *pent; char filename[30]; int i,fcounts = 0; int flag = 0; pdir = opendir(currentDirPath); pent = readdir(pdir); printf("currentDirPath is %s\n", currentDirPath); 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) { int len; 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) { int len = strlen(help)+1; write(sock, help, len); } //command get void cmd_get(int sock, char* fileName) { int fd; struct stat fileSta; long fileSize; char filePath[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) { int fd; long fileSize; char filePath[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 afer the last cha ‘/‘ char *getDirName(char *dirPathName) { int i, pos, len; char *dirName; if(dirPathName == NULL) { printf("directory absoultly path is null\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++) { printf("%c",dirPathName[i]); dirName[i-pos-1] = dirPathName[i]; } return dirName; }
用gcc -o server server.c
如果加上调试信息就是gcc -g -o server server.c
以上是关于ftp服务器的简单实现——服务器端的主要内容,如果未能解决你的问题,请参考以下文章
在vs code中使用ftp-sync插件实现客户端与服务器端代码的同步