tcp文件传输服务器

  • X4_778718
    了解作者
  • 3.9KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-06-14 06:59
    上传日期
tcp文件服务器和客户点,客户端可以上传和下载,支持一些命令help:显示客户端所有命令和说,明,list:显示下载列表,get:下载,put:上传,quit:退出
tcpchuanshuwenjian.rar
  • tcp传输文件
  • ftp-ser.cpp
    5.2KB
  • ftp-cli.cpp
    9.2KB
内容介绍
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h rel='nofollow' onclick='return false;'> #include <dirent.h> #include <errno.h> #include <signal.h> #include <fcntl.h> typedef struct sockaddr SA; //comm format #define GET_FILE 'G' #define PUT_FILE 'P' #define LIST_FILE 'L' #define CMD_OKEY 1 #define CMD_FAIL 0 #define DATA_SZ 256 typedef struct trans_dat { unsigned char cmd; //'L','G','P' unsigned char trn; //trn=0, s<-c; trn=1, s->c unsigned char ack; //cmd fail, ack=0; cmd sucess, ack=1 unsigned char flg; //flg=0, start & end disable unsigned int start; //cmd='G', send start~end unsigned int end; //cmd='G', send start~end unsigned char data[DATA_SZ]; } MSG; //client get file: 1->2->3->4 //step 1: client req file info, s<-c, 1 times // cmd='G', trn=0, ack=x, flg=0, data<=file name //step 2: server ack file info, s->c, 1 times // cmd='G', trn=1, ack=1, flg=0, data<=file length //step 3: client req file data, s<-c, 1 times // cmd='G', trn=0, ack=x, flg=1, data<=file name //step 4: server ack file data, s->c, 1 times // cmd='G', trn=1, ack=1, flg=1, data<=file name //step 5: server ret file data, s->c, n times // MSG<=file content typedef struct cont_seg { unsigned long enable; //segment enable flag unsigned long start; //segment start pos unsigned long end; //segment end pos unsigned long curr; //segment curr pos } SEG; typedef struct cont_inf { SEG seg0; SEG seg1; SEG seg2; SEG seg3; SEG seg4; } CONT; //declare function void wait_child(int sig); void comd_get(char *pFile, struct sockaddr_in * pSrv); void comd_put(char *pFile, struct sockaddr_in * pSrv); void comd_list(struct sockaddr_in * pSrv); void comd_help(void); void trans_cont(char *pFile, struct sockaddr_in * pSrv); void trans_new(char *pFile, struct sockaddr_in * pSrv); int create_file(char *pFile, unsigned long length); int create_cont(CONT *pCont, unsigned long length); void seg_trans(char *pFile, struct sockaddr_in * pSrv, SEG * pSeg); int main(int argc, char * argv[]) { char input[128]; struct sockaddr_in srv_addr; signal(SIGCHLD, wait_child); //recycle child memset(&srv_addr, 0, sizeof(struct sockaddr_in)); srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(12345); srv_addr.sin_addr.s_addr = inet_addr("192.168.1.105"); while (1) { fgets(input, 128, stdin); input[strlen(input) - 1] = 0; //overwrite the '\n' if (strncmp(input, "get ", 4) == 0) { comd_get(input + 4, &srv_addr); } else if (strncmp(input, "put ", 4) == 0) { comd_put(input + 4, &srv_addr); } else if (strcmp(input, "list") == 0) { comd_list(&srv_addr); } else if (strcmp(input, "help") == 0) { comd_help(); } else if (strcmp(input, "quit") == 0) { printf("Bye\n"); break; } else { printf("wrong command, 'help' for command list\n"); } } return 0; } void wait_child(int sig) { wait(NULL); } void comd_get(char *pFile, struct sockaddr_in * pSrv) { int fd; if ((fd = open(pFile, O_CREAT|O_EXCL)) < 0) { trans_cont(pFile, pSrv); } else { trans_new(pFile, pSrv); } return; } void comd_put(char *pFile, struct sockaddr_in * pSrv) { } void comd_list(struct sockaddr_in * pSrv) { } void comd_help(void) { } void trans_cont(char * pFile, struct sockaddr_in * pSrv) { int sckfd; MSG msg; } void trans_new(char * pFile, struct sockaddr_in * pSrv) { int sckfd; MSG msg; CONT cont; if ((sckfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { printf("fail to get\n"); return; } if (connect(sckfd, (SA *) pSrv, sizeof(struct sockaddr_in)) < 0) { printf("fail to connect server\n"); close(sckfd); return; } //step 1: client req file info, s<-c msg.cmd = GET_FILE; msg.trn = 0; msg.flg = 0; strcpy(msg.data, pFile); send(sckfd, &msg, sizeof(msg), 0); //step 2: server ack file info, s->c recv(sckfd, &msg, sizeof(msg), 0); if (msg.cmd == GET_FILE && msg.trn == 1 && msg.ack == CMD_OKEY) { unsigned long length; char buf[128]; int fd; memcpy(&length, msg.data, sizeof(length)); //alloc file space if (create_file(pFile, length)) { printf("creat file %s fail\n", pFile); close(sckfd); return; } create_cont(&cont, length); //save segment to file strcpy(buf, pFile); strcat(buf, ".cfg"); if ((fd = open(buf, O_CREAT|O_WRONLY, 0666)) < 0) { printf("creat config file %s fail\n", buf); close(sckfd); return; } write(fd, &cont, sizeof(cont)); close(fd); //call seg_trans() seg_trans(pFile, pSrv, &cont.seg0); seg_trans(pFile, pSrv, &cont.seg1); seg_trans(pFile, pSrv, &cont.seg2); seg_trans(pFile, pSrv, &cont.seg3); seg_trans(pFile, pSrv, &cont.seg4); } else { printf("No such file\n"); } close(sckfd); return; } int create_file(char * pFile, unsigned long length) { int fd; char buf[1] = {0}; if ((fd = open(pFile, O_CREAT|O_WRONLY, 0666)) < 0) { perror("create_file fail"); return 1; } if (!length) //null file { printf("file length is 0\n"); } else //full file content, alloc file space { lseek(fd, length - sizeof(buf), SEEK_SET); write(fd, buf, sizeof(buf)); } close(fd); return 0; } int create_cont(CONT * pCont, unsigned long length) { if (length < DATA_SZ * 5) //small file { memset(pCont, 0, sizeof(CONT)); pCont->seg0.enable = 1; pCont->seg0.start = 0; pCont->seg0.end = length - 1; pCont->seg0.curr = 0; } else //normal file { //segment 0 setting pCont->seg0.enable = 1; pCont->seg0.start = 0; pCont->seg0.end = length / 5; pCont->seg0.curr = pCont->seg0.start; //segment 1 setting pCont->seg1.enable = 1; pCont->seg1.start = pCont->seg0.end + 1; pCont->seg1.end = length * 2 / 5; pCont->seg1.curr = pCont->seg1.start; //segment 2 setting pCont->seg2.enable = 1; pCont->seg2.start = pCont->seg1.end + 1; pCont->seg2.end = length * 3 / 5; pCont->seg2.curr = pCont->seg2.start; //segment 3 setting pCont->seg3.enable = 1; pCont->seg3.start = pCont->seg2.end + 1; pCont->seg3.end = length * 4 / 5; pCont->seg3.curr = pCont->seg3.start; //segment 4 setting pCont->seg4.enable = 1; pCont->seg4.start = pCont->seg3.end + 1; pCont->seg4.end = length - 1; pCont->seg4.curr = pCont->seg4.start; } return 0; } void seg_trans(char *pFile, struct sockaddr_in * pSrv, SEG * pSeg) { pid_t pid; int sckfd; MSG msg; if (!pSeg->enable) { return; } if (pid = fork()) //parent { return; } else //child { if ((sckfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { printf("fail to get\n"); return; } if (connect(sckfd, (SA *) pSrv, siz
评论