多进程版文件加密系统

来源:互联网 发布:腾讯用的什么编程语言 编辑:程序博客网 时间:2024/06/18 10:15

//客户端向服务器发送加密请求,服务器接收后向客户端提供加密码,并记录保存,解密时客户端发送请求,服务器寻找对应加密码并发送给客户端

//客户端

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

阅读全文
1 0
原创粉丝点击