//客户端向服务器发送加密请求,服务器接收后向客户端提供加密码,并记录保存,解密时客户端发送请求,服务器寻找对应加密码并发送给客户端
//客户端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define MAXLINE 50
#define LEN 1
void sendfile(int sockfd)
{
char sendline[MAXLINE]={0};
char filename[MAXLINE]={0};
char ch;
int password=0;
int n=0,i=0,sum=0;
printf("Connection norma------\n");
printf("input filename :");
scanf("%s",filename);
//发送文件名
if (send(sockfd,filename,strlen(filename),0) == -1)
perror("send error");
//选择加解密
printf("select encrypt or decrypt : [c] | [d] \n");
ch = getchar();
ch = getchar();
//发送加解密
send(sockfd,&ch,1,0);
//接收加解密码
if ((recv(sockfd, &password, sizeof(password), 0)) == -1) {
perror("recv error");
exit(1);
}
printf("password==%d\n",password );
FILE * srcfd;
srcfd = fopen(filename,"r+");
char buf[LEN]={0};
//加解密
while ((n = fread(buf,1, sizeof(buf), srcfd)) > 0)
{
i = 0;
sum += n;
while (i < n)
{
buf[i] ^= password;
i++;
}
fseek(srcfd, -n ,1);
fwrite(buf,1, sizeof(buf), srcfd);
fseek(srcfd, n ,1);
memset(buf, 0, n);
}
printf("\nsum==%d\n", sum);
fclose(srcfd);
}
int main(int argc, char** argv)
{
int sockfd, n, rec_len;
struct sockaddr_in servaddr;
if ( argc != 2) {
printf("usage: ./client <ipaddress>\n");
exit(0);
}
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8000);
if ( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
printf("inet_pton error for %s\n", argv[1]);
exit(0);
}
if ( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
sendfile(sockfd);
close(sockfd);
exit(0);
}
//服务器端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <time.h>
#define DEFAULT_PORT 8000
#define MAXLINE 4096
struct sockaddr_in servaddr, cliaddr;
void receivefile(int arg)
{
int connect_fd = arg;
char buff[MAXLINE] = {0};
char filename[MAXLINE] = {0};
char ch;
FILE* dstfd;
dstfd = fopen("filename.txt","ab");//ab
int password = 0;
//接受客户端发送过来的文件名
recv(connect_fd, filename, MAXLINE, 0);
printf("filename==%s\n",filename );
//接受客户的选择
recv(connect_fd, &ch, 1, 0);
printf("ch==%c\n",ch );
if (ch == 'c')
{ //随机生成加密码
srand((unsigned)time(NULL));
password = rand() % 256;
//向客户端发送加密码
if (send(connect_fd, &password , sizeof(password), 0) == -1)
perror("send error");
//保存文件名及加密码
sprintf(buff, "%s %d\n", filename, password);
fwrite( buff, strlen(buff),1,dstfd);
memset(buff, 0, MAXLINE);
}
else if (ch == 'd')
{
close(dstfd);
dstfd = fopen("filename.txt","r+");
//查找解密码
char filename2[MAXLINE]={0};
//fseek(dstfd, 0 , 0);
while(1)
{
fscanf(dstfd, "%s %d", filename2, &password);
printf("%s--%d\n",filename2,password);
if(strcmp(filename,filename2)==0) break;
sleep(1);
}
//发送解密码
if (send(connect_fd, &password , sizeof(password), 0) == -1)
perror("send error");
}
fclose(dstfd);
close(connect_fd);
}
int main(int argc, char** argv)
{
int socket_fd, connect_fd;
struct sockaddr_in servaddr;
char buff[4096];
//初始化Socket
int i, n;
pid_t pid;
socklen_t cliaddr_len;
if ( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
//初始化
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。
servaddr.sin_port = htons(DEFAULT_PORT);//设置的端口为DEFAULT_PORT
//将本地地址绑定到所创建的套接字上
if ( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
//开始监听是否有客户端连接
if ( listen(socket_fd, 10) == -1) {
printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
printf("======waiting for client's request======\n");
//阻塞直到有客户端连接,不然多浪费CPU资源。
while (1)
{
while (1)
{
int clientfd;
//accept 阻塞等待client连接
memset(&cliaddr, 0, sizeof(cliaddr));
cliaddr_len = sizeof(cliaddr);
if ( (clientfd = accept(socket_fd, (struct sockaddr *)&cliaddr, &cliaddr_len) ) == -1)
{
perror("accept failed");
return 1;
}
else
{
printf("\n\nclient %s:%d connected\n\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
}
int pid = fork();
if ( pid == -1 )
{
printf("fork failed");
}
else if (pid == 0)
{
//子进程关闭被动套接字
close(socket_fd);
receivefile(clientfd);
printf("\n\nclient %s:%d connected close\n\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
return EXIT_FAILURE;
}
else
{
//主进程关闭一个主动套接字clientfd
close(clientfd);
}
}
}
close(socket_fd);
return 0;
}