【Linux实现文件上传下载】

linux 实现文件上传下载(百度云盘)

server:


```c
/*===============================================
*   文件名称:tcp_sev.c
*   创 建 者:     
*   创建日期:2022年09月04日
*   描    述:
================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
 
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
 
 
#define N 128
 
int server_init(char *ip, char *port)
{
	int ret;
	int listenfd;
	struct sockaddr_in srvaddr;
 
	/* 1. 创建服务器(创建一个socket套接字);socket */
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd == -1) {
		perror("server->socket");
		return -1;
	}
	printf("create listenfd = %d success !!\n", listenfd);
 
 
	int opt = 1;
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
 
	/* 2. 设置服务器的IP地址和端口号(将socket和服务器的IP地址和端口号进行绑定);bind */
	memset(&srvaddr, 0, sizeof(struct sockaddr));
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons(atoi(port));
	srvaddr.sin_addr.s_addr = inet_addr(ip);
	ret = bind(listenfd, (const struct sockaddr *)&srvaddr, sizeof(struct sockaddr));
	if(ret == -1) {
		perror("server->bind");
		return -1;
	}
	printf("bind success !!!\n");
	
	/* 3. 启动监听(启动服务器);	listen */
	ret = listen(listenfd, 10);
	if (ret == -1) {
		perror("server->listen");
		return -1;
	}
	printf("listen success !!\n");
 
	return listenfd;
}
 
int server_wait_connect(int listenfd, struct sockaddr *addr, socklen_t *addrlen)
{
	int connfd;
 
	/* 4. 等待客户端的连接请求,如果没有连接请求则等待,如果有连接请求,则建立连接; accept */
	connfd = accept(listenfd, addr, addrlen);
	if (connfd == -1) {
		perror("server->accept");
		return -1;
	}
	printf("connect connfd = %d success \n", connfd);
 
	return connfd;
}
 
 
/* 把服务器上的文件下载到客户端 */
int do_get(int connfd, char *buf)
{
	int ret;
	int fd;
	int filelen;
	int count;
	char *path = buf+4;
    char filebuf[N] = {0};
	struct stat stat_buf;
 
    printf("file: %s\n", path);
	/* 打开文件 */
	fd = open(path, O_RDONLY);
	if (fd == -1) 
    {
		perror("server->open");
		return -1;
	}

	/* 获取文件的大小 */
	ret = stat(path, &stat_buf);
	if (ret == -1) {
		perror("stat");
		return -1;
	}
	filelen = stat_buf.st_size;
 
    printf("=%d\n",filelen);
	/* 发送文件的大小 */
	ret = write(connfd, &filelen, 4);
	if (ret == -1) 
    {
		perror("server->write");
		return -1;
	}

	/* 读取文件内容 */
	while(1) 
    {
		ret = read(fd, filebuf, N);
		if (ret == -1) 
        {
			perror("read");
			return -1;
		}
        if(0 == ret)
            break;

	/* 将文件的数据写入到套接字文件描述符当中*/ 
		int wre = write(connfd, filebuf, ret);
		if (wre == -1) 
        {
			perror("write");
			return -1;
		}
    }
    close(fd);
	return 0;
}
 
/* 将客户端的文件上传到服务器上 */
int do_put(int connfd, char *buf) 
{
    printf("xxxxxxxxxxxx\n");
    int ret;
	int fd;
    char *path = buf + 4;
	int count;
	int filelen;
	char filebuf[N] = {0};

	/* 创建文件 */
	fd = open(path, O_CREAT | O_RDWR, 0777);
	if (fd == -1)
    {
		perror("client->open");
		return -1;
    }

    printf("--------------------\n");
	ret = read(connfd, &filelen, 4);
	if (ret == -1) 
    {
		perror("read");
		return -1;
	}


	/* 读取客户端发送的文件数据 */  //recv
	count = 0;
	while(filelen)
    {
		ret = read(connfd, filebuf, N);
		if (ret == -1)
        {
			perror("read");
			return -1;
		}
	/* 将读取的文件数据写入的文件当中 */

		int wre = write(fd, filebuf, ret);
		if (wre == -1)
        {
			perror("write");
			return -1;
		}
        filelen -= ret;
	}

	close(fd);
    printf("222222222222222222222\n");

	return 0;
}
 
int do_list(int connfd, char *buf)
{
	int ret;
	DIR *dir;
	struct dirent *drt;
 
	dir = opendir(".");
	if (dir  == NULL) {
		perror("opendir");
		return -1;
	}
 
	memset(buf, 0, N);
	while(NULL != (drt = readdir(dir))) {
		if (drt->d_name[0] == '.')
			continue;
		strcat(buf, drt->d_name);
		strcat(buf, "\t");
	}
 
	ret = write(connfd, buf, N);
	if (ret == -1) {
		perror("write");
		return -1;
	}
}

 void do_help(int connfd,char *buf)
{
	printf("/##############################使用手册######################################\n");
    printf("#                 如何查看目录下的所有文件                                  #\n");
	printf("#                    **目录**                                               #\n");
	printf("#	     在<input:> 后面输入  list   你将会查看到所有文件的文件名!     #\n");
	printf("#	                 **下载**                                           #\n");
	printf("#	     在目录下看到的所有文件,需要下载到本地时!                     #\n");
	printf("#	     在<input:> 后面输入  get + 空格 + 文件名                       #\n");
	printf("#        后面将会显示你所下载文件的大小                                     #\n");
	printf("#	                  **上传**                                          #\n");
	printf("#	     当你要将本地文件上传到服务器时!                               #\n");
	printf("#	     在<input:> 后面输入  put + 空格 + 文件名                       #\n");
	printf("#	     后面将会显示你所上传的文件大小!                               #\n");
	printf("#############################################################################\n");   
}

int client_process(int connfd)
{
	int ret;
	char buf[N];
    printf("%d\n",__LINE__);
 
	while(1) 
    {
/* 5. 读写数据:	read/write; */
		memset(buf, 0, sizeof(buf));
 
        ret = read(connfd, buf, sizeof(buf));
 
		if (ret <= 0) 
        {
			perror("server->read");
			return -1; 
		}  
        printf("%s\n", buf); //
		if (strstr(buf, "get")) 
        {
			do_get(connfd, buf);
		} 
        else if (strstr(buf, "put"))
        {
			do_put(connfd, buf);
            printf("============================\n");
		} 
        else if (strstr(buf, "list")) 
        {
			do_list(connfd, buf);
		}
        else if (strstr(buf, "help")) 
        {
			do_help(connfd, buf);
		}
	}
	
	return 0;
}
 
 
 
int main()
{	
    int ret;
	int listenfd;
	int connfd;
	char buf[N];
	struct sockaddr_in cltaddr;
	socklen_t addrlen;
 
	listenfd = server_init("0", "8888");
	if (listenfd == -1) 
		exit(EXIT_FAILURE);
 
	//server_wait_connect(listenfd);	
	while(1) {
		addrlen = sizeof(socklen_t);
		memset(&cltaddr, 0, sizeof(struct sockaddr_in));
		connfd = server_wait_connect(listenfd, (struct sockaddr *)&cltaddr, &addrlen);
		if (connfd == -1) 
			exit(EXIT_FAILURE);
 
		client_process(connfd);
		close(connfd);
	}
	/* 6. 关闭	close; */
	close(listenfd);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值