本文主要是介绍项目:基于TCP的文件传输系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
项目介绍:
模拟FTP原理:客户端连接服务器后,向服务器发送一个文件。文件名可以通过参数指定,服务器端接收客户端传来的文件(文件名随意),如果文件不存在自动创建文件,如果文件存在,那么清空文件然后写入。
项目技术点:
TCP客户端和服务器的搭建
目录IO获取路径下的文件名用于展示
标准IO或文件IO的打开,读取以及写入操作文件
TCP协议需要考虑如何防止粘包的发生(建议发送和接收的大小一致)
参考内容:
(1)client.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;int main(int argc, const char* argv[]){//1.socketint sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd < 0){perror("socket is error:");return -1;}//绑定套接字struct sockaddr_in saddr,caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[2]));saddr.sin_addr.s_addr = inet_addr(argv[1]);char buf[128];if(connect(sockfd,(struct sockaddr *)&saddr,sizeof(saddr)) < 0){perror("connect is error:");return -1;}while(1){//选择功能printf("功能1--------list--------\n");printf("功能2--------put--------\n");printf("功能3--------get--------\n");printf("功能4--------quit-------\n");printf("请选择功能:\n");int num;scanf("%d",&num);//显示该目录下的所有文件if(num == 1){send(sockfd,&num,4,0);while(1){char stu[128];int flag = 1;send(sockfd,&flag,4,0);int res = recv(sockfd,stu,sizeof(stu),0);printf("%s\n",stu);if(stu[0] == 0){break;}}}//上传文件else if(num == 2){printf("请输入要上传的文件名\n");send(sockfd,&num,4,0);char stu[512];scanf("%s",stu);//以只读形式打开已有文件int fd = open(stu,O_RDONLY);//判断文件是否存在if(access(stu,F_OK) == -1){printf("输入文件不存在,请重新输入:\n");break;} while(1){char s[512];int flag = 0;int res = read(fd,s,sizeof(s));if(res == 0){break;}send(sockfd,s,sizeof(s),0);recv(sockfd,&flag,4,0);}printf("上传成功\n");}//下载文件else if(num == 3){send(sockfd,&num,4,0);printf("请输入要下载的文件\n");char c[32];scanf("%s",c);if(c[strlen(c)-1] == '\n')c[strlen(c)-1] = '\0'; send(sockfd,c,32,0); //创建新的文件并打开 int fd = open(c,O_WRONLY | O_TRUNC | O_CREAT,0666);char ct[256]=""; while(1){int flag = 1;int res = recv(sockfd,ct,sizeof(ct)-1,0);if(strlen(ct)==0){break;}//写入新的文件内,下载成功write(fd,ct,strlen(ct));}printf("下载成功\n");//关闭文件close(fd);}//退出(仅客户端),服务端仍然等待其他客户端连接else if(num == 4){send(sockfd,&num,4,0); }else{printf("抱歉,您输入的数字有误,请重新输入\n");}}close(sockfd); return 0;
}
(2)server.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <dirent.h>typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;int main(int argc, const char* argv[])
{//1.socketint sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd < 0){perror("socket is error:");return -1;}//绑定套接字struct sockaddr_in saddr,caddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));saddr.sin_addr.s_addr = inet_addr("0.0.0.0");int len = sizeof(caddr);char buf[128];if(bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr)) < 0){perror("bind is error:");return -1;}if(listen(sockfd,5) < 0){perror("listen is error:");return -1;}while(1){printf("-------等待客户端连接-----------\n");int acceptfd = accept(sockfd,(struct sockaddr *)&caddr,&len);if(acceptfd < 0){perror("accept is error:");return -1;}printf("-------客户端连接成功------------\n");while(1){int num;printf("请选择功能\n");int res = recv(acceptfd,&num,sizeof(num),0);if(res < 0){perror("recv is error:");return -1;}else if(res == 0){printf("recv is exit:\n");break;}else{if(num == 1){struct dirent *file = NULL;DIR *dp = opendir("./");if (dp == NULL) {perror("opendir is error:");return -1;}while((file = readdir(dp)) != NULL) {if(file->d_name[0] == '.' ){continue;}int flag = 0;recv(acceptfd,&flag,4,0);send(acceptfd,file->d_name,128,0);}int flag = 0;recv(acceptfd,&flag,4,0);char bb[128] ={0};send(acceptfd,bb,128,0);}else if(num == 2){//新建文件并打开int fd = open("./3",O_WRONLY | O_TRUNC | O_CREAT,0666);while(1){char ss[512];int flag = 1;//接收内容int res = recv(acceptfd,ss,sizeof(ss),0);if(res == 0){break;}//写入write(fd,ss,strlen(ss));send(acceptfd,&flag,4,0); }//关闭文件close(fd);}else if(num == 3){printf("进入功能:\n");char c[32] = {0};recv(acceptfd,c,32,0);printf("%s\n",c);int fd = open(c,O_RDONLY);while(1){char st[256]="";int flag=1; int res = read(fd,st,sizeof(st)-1);//阻塞性接收并传送回文件数据与内容if(res == 0){char dt[256]=""; send(acceptfd,dt,sizeof(dt)-1,0);break;}if(flag==1){send(acceptfd,st,sizeof(st)-1,0); }}}else if(num == 4){break;}else{printf("抱歉,您输入的数字有误,请重新输入\n");} }}}
close(sockfd);
return 0;
}
这篇关于项目:基于TCP的文件传输系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!