自己实现一个简单的ftp软件
来源:互联网 发布:软件项目沟通机制 编辑:程序博客网 时间:2024/06/07 12:21
近期面试有个机试题是写个ftp软件,自己写完不想就扔了,就放到这里大家参考一下,也帮我优化优化,没什么太难的也就不需要什么注释了
消息格式:
cmd | size | data
服务端:
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <arpa/inet.h>#include <netinet/in.h>#include <dirent.h>#include <stdlib.h>#define COMPARE(a, b, c) (strcmp(a, c) b 0) #define HEAD_SIZE 4char *packet(int size, const char *data);int main(int argc, const char *argv[]){ int sockfd, acceptfd; struct sockaddr_in myaddr; memset(&myaddr, 0, sizeof(myaddr)); socklen_t addrlen = sizeof(struct sockaddr_in); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) return -1; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(6060); myaddr.sin_addr.s_addr = inet_addr("192.168.255.128"); int optval = 1; socklen_t optlen = sizeof(optval); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen); //设置端口重用 if (bind(sockfd, (struct sockaddr *)&myaddr, addrlen) == -1) { printf("bind faild\n"); return -1; } if (listen(sockfd, 10) == -1) { printf("listen faild\n"); return -1; } if ((acceptfd=accept(sockfd, (struct sockaddr *)&myaddr, &addrlen)) == -1) { printf("acceptfd faild\n"); return -1; } ssize_t recvlen, sendlen; char buf[256]; DIR *dirfd; while (1) { //注意服务端使用的消息格式是size|data recv(acceptfd, buf, 4, 0); //先接收开始的四个字节cmd if (COMPARE(buf, ==, "get")) { memset(buf, 0, 0); recv(acceptfd, buf, 4, 0); int size = *(int *)buf; recv(acceptfd, buf, size, 0); printf("%s\n", buf); FILE *fp = fopen(buf, "rb"); if (fp == NULL) { printf("file open failed\n"); break; } memset(buf, 0, 0); //使用buf前先清空一下,防止出现其它不想要的字符 size_t readlen = fread(buf, 1, sizeof(buf), fp); char *tmp = packet(readlen, buf); send(acceptfd, tmp, HEAD_SIZE+readlen, 0); free(tmp); fclose(fp); } else if (COMPARE(buf, ==, "ls")) { printf("%s\n", buf); if ((dirfd = opendir("./")) == NULL) { char *tmp = packet(8, "no file"); send(sockfd, tmp, HEAD_SIZE + 8, 0); free(tmp); printf("file open failed\n"); } else { struct dirent *pdirent; while ((pdirent = readdir(dirfd)) != NULL) { if (pdirent->d_name[0] == '.') continue; char *tmp = packet(strlen(pdirent->d_name)+1, pdirent->d_name); sendlen = send(acceptfd, tmp, HEAD_SIZE + strlen(pdirent->d_name)+1, 0); if (sendlen == 0) break; free(tmp); } char *tmp = packet(4, "ok"); send(acceptfd, tmp, HEAD_SIZE + 3, 0); } } else if (COMPARE(buf, ==, "put")) { printf("%s\n", buf); recv(acceptfd, buf, 4, 0); int size = *(int *)buf; memset(buf, 0, 0); size_t recvlen = recv(acceptfd, buf, size, 0); FILE *fp = fopen("./update.txt", "wb"); if (fp == NULL) { printf("file open failed\n"); break; } fwrite(buf, 1, recvlen, fp); strcpy(buf, "ok"); send(acceptfd, buf, 3, 0); fclose(fp); } } close(sockfd); close(acceptfd); return 0;}char *packet(int size, const char *data) { char *ret = malloc(sizeof(int) + size); *(int *)ret = size; memcpy(ret + HEAD_SIZE, data, size); return ret;}
客户端:
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <arpa/inet.h>#include <netinet/in.h>#include <stdlib.h>#define COMPARE(a, b, c) (strcmp(a, c) b 0)#define HEAD_SIZE 8char *packet(const char *cmd, int size, const char *data);int main(int argc, const char *argv[]){ int sockfd; struct sockaddr_in myaddr; memset(&myaddr, 0, sizeof(myaddr)); socklen_t addrlen = sizeof(struct sockaddr_in); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) return -1; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(6060); myaddr.sin_addr.s_addr = inet_addr("192.168.255.128"); if (connect(sockfd, (struct sockaddr *)&myaddr, addrlen) == -1) { printf("connect faild\n"); return -1; } ssize_t recvlen, sendlen; char buff[256]; char send_buff[256]; char recv_buff[256]; char *token = NULL; char *delim = " "; while (1) { printf("ftp > "); fgets(buff, sizeof(buff), stdin); buff[strlen(buff) - 1] = 0; char *tmp = buff; if (*tmp == 0) continue; token = strtok(tmp, delim);#if 1 if (COMPARE(token, ==, "ls")) { char *send_data = packet("ls", 0, NULL); send(sockfd, send_data, HEAD_SIZE, 0); free(send_data); while (1) { recvlen = recv(sockfd, recv_buff, 4, 0); if (recvlen <= 0) break; int size = *(int *)recv_buff; memset(recv_buff, 0, 0); recv(sockfd, recv_buff, size, 0); if (COMPARE(recv_buff, ==, "ok")) break; printf("%s ", recv_buff); fflush(stdout); } printf("\n"); } else if (COMPARE(token, ==, "get")) { char *data = strtok(NULL, delim); char *send_data = packet("get", strlen(data) + 1, data); send(sockfd, send_data, HEAD_SIZE+strlen(data)+1, 0); free(send_data); recvlen = recv(sockfd, recv_buff, 4, 0); if (recvlen <= 0) break; int size = *(int *)recv_buff; memset(recv_buff, 0, 0); recvlen = recv(sockfd, recv_buff, size, 0); FILE *fp = fopen(data, "wb"); size_t len = fwrite(recv_buff, 1, recvlen, fp); printf("file download\n"); fclose(fp); } else if (COMPARE(token, ==, "put")) { char *data = strtok(NULL, delim); FILE *fp = fopen(data, "rb"); if (fp == NULL) { printf("file open failed\n"); continue; } size_t readlen = fread(send_buff, 1, sizeof(send_buff), fp); char *tmp = packet("put", readlen, send_buff); send(sockfd, tmp, HEAD_SIZE+readlen, 0); free(tmp); fclose(fp); memset(recv_buff, 0, 0); recv(sockfd, recv_buff, 3, 0); if (COMPARE(recv_buff, ==, "ok")) printf("put file finish\n"); } else if (COMPARE(token, ==, "quit")) { close(sockfd); return 0; }#endif } close(sockfd); return 0;}char *packet(const char *cmd, int size, const char *data) { char *ret = malloc(sizeof(char *) + sizeof(int) + size); memcpy(ret, cmd, 4); *(int *)(ret + 4) = size; if (size != 0) memcpy(ret + HEAD_SIZE, data, size); return ret;}
显示结果:
一个简单的ftp软件就实现了,不过有太多的缺陷和问题,等以后修改了再更新
阅读全文
0 0
- 自己实现一个简单的ftp软件
- 一个简单的FTP客户端 实现上传下载
- Java实现一个简单的FTP客户端
- Java语言实现简单FTP软件------>FTP软件主界面的实现(四)
- Java语言实现简单FTP软件------>FTP软件本地窗口的实现(五)
- Java语言实现简单FTP软件------>FTP软件远程窗口的实现(六)
- 自己写的一个hibernate简单实现
- 自己实现一个简单的Promise
- 自己实现一个最简单的数据库
- 自己实现一个最简单的数据库
- 自己实现一个最简单的数据库
- 自己实现一个简单版的HashMap
- 自己实现一个简单的AVL树
- 自己实现一个简单的散列表
- 自己实现一个简单的RPC框架
- 自己实现一个简单的读写锁
- 自己实现一个简单的ArrayList
- Java语言实现简单FTP软件------>辅助功能模块FTP站点管理的实现(十二)
- Swift之自定义标签栏UITabBarController (Swift项目开始的第一步)
- java编写Dijkstra单源最短路径算法
- 数据结构:点对之间最短距离--Floyd算法
- Node.js原生开发入门完全教程
- 单调队列初步
- 自己实现一个简单的ftp软件
- CSS盒模型
- spring booot多环境配置
- 【React Native】Mac端iOS和Android开发环境搭建完全教程
- LNMP时,出现502 Bad Gateway的错误提示
- Apache Kylin构建cube的FactDistinctColumnsJob阶段出现IllegalStateException异常
- web页面a标签触发事件
- 15分钟搭建独立电子书博客
- JAVA-WEB Hibernate面试整理