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;
}