准备工作
1、base64的加密与解密的方法有很多种,可以直接使用Linux自带的base64命令,也可以使用一些base64库,或者base64源代码等等。
2、这里我使用的是在Gethub官网上下载的一个评价最高的base64包,先下载一下:
我先说明一下,这个包代码结构比较复杂,编译也需要更改一些东西,如果是大神建议直接下载第一个,可自行编译得到所需库文件,小白建议直接下载我编译好的两个库文件,也就是第二、三个。
(一)源base64包:
链接:https://pan.baidu.com/s/16cC4qOVCiascjvwuEbHlpg
提取码:lgi0
(二)64位系统下下载:
链接:https://pan.baidu.com/s/1mbTFmoPZsBEylw2I9M4uEA
提取码:zbxn
(三)32位arm开发板下载:
链接:https://pan.baidu.com/s/13Qop78nCKk-RHFLrLBeLMA
提取码:a6ch
电脑与电脑之间的传输
一、首先确定两台电脑是否处于同一局域网内
1、可以在教室或者工作室插上处于同一局域网的网线
2、可以利用一根网线实现电脑与电脑直连
二、下载好第二个base64包
你将会得到这样两个文件
使用它时只需要包含 libbase64.h 头文件,编译时链接静态库即可
三、编写测试代码
测试这个base64包是否能够编码与解码
#include <stdio.h>
#include <libbase64.h>
#include <string.h>
int main(int argc,const char **argv)
{
char buf[] = "12345";
char base_buf[100];
//base64加密
size_t len;
bzero(base_buf,strlen(base_buf));
base64_encode(buf,strlen(buf),base_buf,&len,0);
printf("base_buf:%s \n",base_buf);
//base64解码
bzero(buf,strlen(buf));
base64_decode(base_buf,strlen(base_buf),buf,&len,0);
printf("解码后:%s\n",buf);
return 0;
}
编译命令:gcc main.c -o main -L. lbase64
运行:
三、编写代码
代码需要依赖:libbase64.a、libbase64.h下载第二个文件包即可。
需要两个代码,一个是发送文件,一个是接收文件
接收方:
recv.c
/*TCP客户端*/
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <libbase64.h>
#define SERV_PORT 6666
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("input error:try './recv 192.168.18.66'\n");
exit(0);
}
int cfd;
int conter = 10;
char buf[BUFSIZ];
struct sockaddr_in serv_addr; //服务器地址结构
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
//inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr.s_addr);
inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
cfd = socket(AF_INET, SOCK_STREAM, 0);
if (cfd == -1)
sys_err("socket error");
int ret = connect(cfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (ret != 0)
sys_err("connect err");
struct stat sta;
char name[64];
read(cfd,name,sizeof(name));
printf("文件名:%s\n",name);
read(cfd,&sta.st_size,sizeof(sta.st_size));
printf("文件大小:%ld\n",sta.st_size);
//准备文件
int fd = open(name,O_WRONLY|O_CREAT|O_APPEND|O_TRUNC,0666);
char *file_buf = (char *)malloc(sta.st_size+100);
char *decode_file_buf = (char *)malloc(sta.st_size*3/4+100);
//read(cfd,file_buf,sta.st_size);
int n_read;
unsigned long total=0;
while(1)
{
if(sta.st_size-total>=10*1024)
{
n_read = read(cfd,file_buf+total,10*1024);
total += n_read;
printf("读出%d字节:\n",n_read);
}else if(sta.st_size-total<10*1024)
{
n_read = read(cfd,file_buf+total,sta.st_size-total);
total += n_read;
printf("读完了:一共%ld字节\n",total);
break;
}
if(n_read < 0)
{
printf("读取出错\n");
exit(0);
}
}
//解码
long len;
base64_decode(file_buf,sta.st_size,decode_file_buf,&len,0);
printf("解码后文件大小:%ld字节\n",len);sleep(1);
//开始写入文件
write(fd,decode_file_buf,len);
close(fd);
close(cfd);
close(cfd);
return 0;
}
发送方:
send.c
/*TCP服务器*/
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <libbase64.h>
#define SERV_PORT 6666
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("输入:./main a.txt\n");
exit(1);
}
int lfd = 0, cfd = 0;
int ret, i;
char buf[BUFSIZ], client_IP[BUFSIZ];
struct sockaddr_in serv_addr, clit_addr;
socklen_t clit_addr_len;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
lfd = socket(AF_INET, SOCK_STREAM, 0);
if (lfd == -1) {
sys_err("socket error");
}
int on = 1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
listen(lfd, 128);
clit_addr_len = sizeof(clit_addr);
cfd = accept(lfd, (struct sockaddr *)&clit_addr, &clit_addr_len);
if (cfd == -1)
sys_err("accept error");
printf("client ip:%s port:%d\n",
inet_ntop(AF_INET, &clit_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),
ntohs(clit_addr.sin_port));
int fd = open(argv[1],O_RDONLY,0666);
if(fd == -1){
perror("open failed");
exit(0);
}
struct stat sta;
if(stat(argv[1],&sta)==-1){
perror("stat failed");
exit(0);
}
printf("文件:%s\n",argv[1]);
printf("大小:%ld\n",sta.st_size);
char *file_buf = (char *)malloc(sta.st_size+100);
char *encode_file_buf = (char *)malloc(sta.st_size*4/3+100);
//read(fd,file_buf,sta.st_size);
int n_read;
unsigned long total=0;
while(1)
{
lseek(fd,total,SEEK_SET);
n_read = read(fd,file_buf+total,10*1024);
total += n_read;
if(n_read > 0)
{
printf("读出%d字节:\n",n_read);
}else if(n_read == 0)
{
printf("读完了:一共%ld字节\n",total);
break;
}else if(n_read < 0)
{
printf("读取出错\n");
exit(0);
}
}
//编码
long len;
base64_encode(file_buf,sta.st_size,encode_file_buf,&len,0);
//告诉对方文件名
write(cfd,argv[1],strlen(argv[1]));
usleep(10000);
//告诉对方要发多少字节过来
write(cfd,&len,sizeof(len));
usleep(10000);
printf("编码后文件大小:%ld字节\n",len);
//开始发送文件
//write(cfd,encode_file_buf,len);
int n_write;
unsigned long w_total=0;
while(1)
{
//sleep(1);
if(len-w_total>=10*1024)
{
n_write = write(cfd,encode_file_buf+w_total,10*1024);
w_total += n_write;
printf("发送%d字节:\n",n_write);
}
else if(len-w_total<10*1024)
{
n_write = write(cfd,encode_file_buf+w_total,len-w_total);
w_total += n_write;
printf("发完了:一共%ld字节\n",w_total);
break;
}
if(n_write < 0)
{
printf("发送出错\n");
exit(0);
}
}
close(lfd);
close(cfd);
return 0;
}
运行:
由于只有一台电脑,就直接连接本地回环地址127.0.0.1,发送到本地。
两台电脑也做过实验,发送成功。
(注意看下面文件位置与执行命令格式)
可以看到文件已经发送过去了
文件也是正常的,没有丝毫损坏。
电脑与开发板之间的传输
不多说了,这个代码耗费博主半条命研究出来的,直接分享给大家,记得点赞支持。
百度网盘链接:https://pan.baidu.com/s/1R0iVbMEDxACbsPxXCE3QCA
提取码:p1t6