一. 基本傳輸子系統程序設計linux
客戶端可上傳文件至服務器,或下載服務器上的文件算法
系統程序構架:服務器
客戶端 | 服務器 |
TCP創建鏈接網絡 menu()-> 上傳命令、下載命令框架 close(socket)socket |
TCP創建鏈接函數 handle()-> 根據命令響應工具 close(socket);優化 |
主函數框架:加密
客戶端 | 服務器 |
int main(int argc, char *args[]) { if (argc != 2) { printf("usage:./client 192.168.10.18(serverip)"); exit(0); //退出 } strcpy(ipaddr,args[1]); //將服務器地址放入字符串中 //1.創建鏈接 clink(); //2.輸入命令, 實現上傳和下載,實現菜單 menu(); //3.關閉鏈接 close(sockfd); return 0; } int clink() { //1.建立socket sockfd = socket(AF_INET, SOCK_STREAM, 0);//IPv4 /*2.1 初始化地址*/ memset(&sockaddr1,0,sizeof(sockaddr1));//清零 sockaddr1.sin_family = AF_INET;//協議族 sockaddr1.sin_addr.s_addr = inet_addr(ipaddr);// sockaddr1.sin_port = htons(port);//端口,跟隨網絡傳輸, //2.鏈接服務器 connect(sockfd,(struct sockaddr *)&sockaddr1,
|
int main() { //1.1建立socket sockfd = socket(AF_INET, SOCK_STREAM, 0); //IPv4,用於TCP通訊 //1.2綁定地址 /*初始化地址*/ bzero(&server_addr,sizeof(struct sockaddr_in));//清零 server_addr.sin_family = AF_INET;//協議族 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//跟隨網絡傳輸 server_addr.sin_port = htons(port);//端口,跟隨網絡傳輸 /*綁定地址*/ |
---------------------------------------------------------------------------------------
客戶端操做菜單及服務器端命令響應:
客戶端操做菜單 | 服務器端命令響應 |
1 void menu() 2 { 3 while(1) 4 { 5 printf("\n-------- 1. Upload Files -----------\n"); 6 printf("-------- 2. Download Files ----------\n"); 7 printf("--------------- 3. Exit ------------\n"); 8 printf("Please input the Client command:"); 9 command = getchar(); //等待用戶輸入字符 10 switch(command) 11 { 12 case '1': 13 { //上傳文件 14 while ((c=getchar()) != '\n' && c != EOF);//獲鍵盤輸入文件名 15 fgets(file_u,30,stdin); //stdin 標準輸入 16 upload_file(file_u); //上傳 17 } 18 case '2': 19 { //下載文件 20 while ((c=getchar()) != '\n' && c != EOF); 21 fgets(file_d,30,stdin); //stdin 標準輸入 22 download_file(file_d); //下載 23 }
|
按照客戶端的合適進行設定 //1.接收操做符--->>>第一部曲 --->>>1步 read(new_fd,&cmd,1); //讀取操做類型碼 //2.按照操做符進行命令函數 if(cmd == 'Q') { close(new_fd); break;} else handle(cmd); //3.進行正式文件處理--->>>剩下4部曲
|
//case "1" 上傳文件 5部曲 void upload_file(char *filename) { //1.打開要上傳的文件 fd = open(filename,O_RDONLY); //以只讀方式打開文件 //2.發送操做符 cmd="U" write(sockfd,&cmd,1); //3.發送要上傳的文件名 write(sockfd,filename,size); //4.發送文件長度 stat(filename,&fstat); //獲取文件屬性 write(sockfd,(void *)&(fstat.st_size),4); //5.發送文件 while((count=read(fd,(void *)buf,1024))>0)//讀取來的數據存到buf的空間 write(sockfd,&buf,count); } //case "2" 下載文件 5部曲相同 void download_file(char *filename) { //1.發送操做符 cmd="D" write(sockfd,&cmd,1); //2.發送要下載的文件名 write(sockfd,filename,size); //3.建立接收文件 fd = open(filename,O_RDONLY|O_CREAT,0777); //以只讀方式打開文件 //4.接收文件長度 read(sockfd,&filesize,4); //5.接收文件 while((count=read(fd,(void *)buf,1024))>0)//讀取來的數據存到buf的空間 write(fd,&buf,count); } |
-------------------------------------------------------------------------------------------------------------------
二. OpenSSL加密系統
因爲網絡傳輸數據中,易被抓包軟件截獲。所以運用非對稱加密方法(公鑰、私鑰、數字證書),文件內容+公鑰 ->加密系統 ->私鑰,方可解密文件。
a)公鑰與私鑰是配對時候用的;
b)私鑰加密的文件一樣用對應的公鑰解密,而爲了區分公鑰(防止公鑰被偷換,致使私密文件泄露),引入數字證書再加密。
c)數字證書有權威機構發放,包含公鑰及持有人信息,沒法丟失假冒;
![]() |
SSL協議處於應用層協議(HTTP/SMTP)與TCP/IP協議之間,可實現文件加密傳輸。開源套接字層密碼庫OpenSSL,包含SSL、密碼算法、祕鑰證書管理功能等。 |
-----------------------------------------------------------------------------------------------
移植OpenSSL庫:
解壓安裝文件 -> 配置.config文件,修改交叉工具鏈arm-linux- -> 編譯make,make install,即生成OpenSSL的庫函數文件 .a、.so -> 置於/rootfs/lib/目錄下,OK!
OpenSSL通信模型:基於下列通信模型優化原始傳輸子系統程序設計
客戶端SSL模型 | 服務器端SSL模型 |
初始化SSL -> (建立套接字、鏈接服務器) -> 建立SSL -> 基於SSL收發數據 -> 關閉SSL -> (關閉套接字) |
初始化SSL -> 公鑰私鑰數字證書設置 -> (建立套接字、綁定、等待鏈接) -> 建立SSL -> 基於SSL收發數據 -> 關閉SSL -> (關閉套接字) |
基於SSL收發數據:將write (sockfd,~) ->SSL_write (ssl,~)、read (sockfd,~) ->SSL_read (ssl,~)便可!
再對應產生公鑰、私鑰:(所有置於服務器目錄下)
# openssl genrsa -out privkey.pem 2048 ->私鑰
# openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 ->對應產生的公鑰
OpenSSL加密傳輸子系統程序設計完成,對應產生服務器加密所需的公鑰與私鑰,分別進行編譯便可實現:對上傳、下載服務器文件的加密傳輸。