當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]開發(fā)環(huán)境:ubuntu所用知識點:c,socket, tcp/ip協(xié)議A)本實驗主要實現(xiàn)tftp協(xié)議的服務(wù)器與客戶端。服務(wù)器實現(xiàn)功能有:1)接收處理客戶端請求,上傳下下載文件2)進(jìn)行用戶驗證3)對傳輸

開發(fā)環(huán)境:ubuntu

所用知識點:c,socket, tcp/ip協(xié)議

A)本實驗主要實現(xiàn)tftp協(xié)議的服務(wù)器與客戶端。

服務(wù)器實現(xiàn)功能有:

1)接收處理客戶端請求,上傳下下載文件

2)進(jìn)行用戶驗證

3)對傳輸數(shù)據(jù)進(jìn)行加密解密處理

4)生成日志文件

客戶端實現(xiàn)功能有:

1)向服務(wù)器發(fā)出請求,上傳或下載文件

2)對傳輸數(shù)據(jù)加密解密

3)對用戶信息進(jìn)行MD5加密

B)相關(guān)代碼實現(xiàn):

宏定下:

#ifndef MAKEWORD

#define MAKEWORD(l,h) ((unsigned short)(((unsigned char)(l))|(((unsigned short)(unsigned char)(h))<<8)))

#endif

#define WSA_MAJOR_VERSION 1

#define WSA_MINOR_VERSION 1

#define WSA_VERSION MAKEWORD(WSA_MAJOR_VERSION, WSA_MINOR_VERSION)

#define TFTP_OCTET 1

#define TFTP_WSTAT_FIRSTACK 0

#define TFTP_WSTAT_NEXTACK 1

#define TFTP_WSTAT_LASTACK 2

#define TFTP_RRQ 1 //讀請求

#define TFTP_WRQ 2 //寫請求

#define TFTP_DATA 3 //數(shù)據(jù)

#define TFTP_ACK 4 //ACK

#define TFTP_ERROR 5 //Error

#define MAX_RETRY 3 //最大重復(fù)次數(shù)

#define TFTP_NOTEND_DATALEN 512+2+2 //數(shù)據(jù)塊長度

//錯誤種類

#define Not_defined 0

#define File_not_found 1

#define Access_violation 2

#define Disk_full 3

#define Illegal_TFTP_operation 4

#define Unknown_port 5

#define File_already_exists 6

#define No_such_user 7

#define Time_out 8

#define Read_file_Error 9

#define Cannot_create_file 10

#define passwd_or_user_error 11

包的填充:

#include "define.h"

#include

#include

int makeack(unsigned short num,char *buffer,int size );

int makedata(unsigned short num,char *data,int datasize,char *buffer,int bufsize);

int makeerr(unsigned short num,char *buffer);

//ACK包填充

int makeack(unsigned short num,char *buffer,int size )

{

int pos = 0;

buffer[pos] = 0;

pos++;

buffer[pos] = TFTP_ACK; //操作碼為04

pos++;

buffer[pos] = (char)(num>>8);//塊號2個字節(jié)

pos++;

buffer[pos] = (char)num;

pos++;

return pos;

}

//Data包填充

int makedata(unsigned short num,char *data,int datasize,char *buffer,int bufsize)

{

int pos = 0;

buffer[pos] = 0;

pos++;

buffer[pos] = TFTP_DATA; //操作碼為03

pos++;

buffer[pos] = (char)(num>>8);//塊號

pos++;

buffer[pos] = (char)num;

pos++;

memcpy(&buffer[pos],data,datasize);//填充數(shù)據(jù)

pos = pos + datasize;

return pos;

}

//ERROR包填充

int makeerr(unsigned short num,char *buffer)

{

int pos=0;

buffer[pos]=0;

pos++;

buffer[pos]=TFTP_ERROR; //操作碼為05

pos++;

buffer[pos] = (char)(num>>8); //錯誤種類號

pos++;

buffer[pos] = (char)num;

pos++;

return pos;

}

日志log.c實現(xiàn)

#include

static char log[100]; //日志

char datetime[20]; //記錄時間變量

int timeout=2,retran=3; //服務(wù)器參數(shù)

void record(int a,struct sockaddr_in *sin,char *file)

{

char tem[60];

time_t t=time(0); //初始化日歷時間

strftime(datetime,sizeof(datetime),"%y/%m/%d %X",localtime(&t));//將時間格式化

strcat(log,datetime);//將時間寫入記錄

//將字符串格式化

bzero(&tem,sizeof(tem));

if(a==1)

sprintf(tem," 收到來自 %s 上傳文件 %s 的請求。n",inet_ntoa(sin->sin_addr),file);

if(a==2)

sprintf(tem," %s 上傳文件 %s 完畢。n",inet_ntoa(sin->sin_addr),file);

if(a==3)

sprintf(tem," 收到來自 %s 下載文件 %s的請求。n",inet_ntoa(sin->sin_addr),file);

if(a==4)

sprintf(tem," %s 下載文件 %s 完畢。n",inet_ntoa(sin->sin_addr),file);

if(a==5)

sprintf(tem," 出現(xiàn)出錯,操作中斷。n",inet_ntoa(sin->sin_addr),file);

//將具體信息寫入記錄

strcat(log,tem);

FILE *write;

if((write=fopen("log.txt","a+"))==NULL)

printf("打開記錄文件失敗n");

//將記錄寫入文件

fwrite(&log,strlen(log),1,write);

fclose(write);

bzero(&log,sizeof(log));

}

加密解密實現(xiàn)

#include

#include

#include

int decrypt(FILE *in,FILE *out);

int encrypt(FILE *in,FILE *out);

unsigned char atoh(char *hexstr);

int encrypt(FILE *in,FILE *out)

{

if(in == NULL || out == NULL)

{

fprintf(stderr,"%sn","file error!n");

return -1;

}

unsigned char hex;

while(fread(&hex,1,1,in))

{

hex = ~hex^0x98;

fprintf(out,"%02X",hex);

}

return 0;

}

int decrypt(FILE *in,FILE *out)

{

if(in == NULL || out == NULL)

{

fprintf(stderr,"%sn","file error!");

return -1;

}

unsigned char hexstr[3];

unsigned char hex = 0;

int i = 0;

while(fread(hexstr,2,1,in))

{

hex = atoh(hexstr);

hex = ~(hex ^ 0x98);

fwrite(&hex,1,1,out);

}

return 0;

}

/* convert string to hex */

unsigned char atoh(char *hexstr)

{

int i;

int hextodec[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

char chtodec[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

unsigned char hexnum = 0;

for(i = 0; i < sizeof(chtodec); ++i)

{

if(hexstr[0] == chtodec[i])

{

hexnum += hextodec[i]*16;

}

}

for(i = 0; i < sizeof(chtodec); ++i)

{

if(hexstr[1] == chtodec[i])

{

hexnum += hextodec[i];

}

}

return hexnum;

}

上傳數(shù)據(jù):

//上傳函數(shù)

void upload(struct sockaddr_in sour_addr,char buffer[])

{

char send_buffer[1024] = {0};

char recv_buffer[1024] = {0};

struct sockaddr_in dest_addr;

struct timeval timeout = {10,0};

int sour_len = 0;

int ret = 0;

int len = 0;

int flen = 0;

fd_set fdr;

unsigned short lastdata = 0;

unsigned short blocknum = 0;

FILE *file;

FILE *decrypt_file = NULL;

char filename[256];

//獲取文件名

strcpy(filename,buffer+2);

dest_addr.sin_family = AF_INET;

dest_addr.sin_port = sour_addr.sin_port;

dest_addr.sin_addr.s_addr = inet_addr(desthost);//

//如果本地存在同名文件

if((file=fopen(filename,"rb"))!=NULL)

{

//發(fā)送一個error包,報告存在同名文件

printf("***存在同名文件***");

len = makeerr(File_already_exists,send_buffer);

ret = sendto(sock,send_buffer,len,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));

record(5,&sour_addr,filename);

return;

}

//建立文件

if((file=fopen(filename,"w+b"))==NULL)

{

//如果失敗,發(fā)送error包

printf("創(chuàng)建文件失敗n");

len = makeerr(Cannot_create_file,send_buffer);

ret = sendto(sock,send_buffer,len,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));

record(5,&sour_addr,filename);

return;

}

//發(fā)送ACK

len = makeack(blocknum,send_buffer,sizeof(send_buffer));

ret = sendto(sock,send_buffer,len,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));

blocknum++;

while(1){

FD_ZERO(&fdr);

FD_SET(sock, &fdr);

ret = select(sock+1, &fdr, NULL,NULL, &timeout);

if(-1==ret)

{

printf("Socket 錯誤n");

fclose(file);

record(5,&sour_addr,filename);

return;

}

else

{

if(0==ret)

{

printf("超時n");

fclose(file);

record(5,&sour_addr,filename);

return;

}

else

{

if (FD_ISSET(sock,&fdr))

{

//接收數(shù)據(jù)包

sour_len = sizeof(struct sockaddr);

ret = recvfrom(sock,recv_buffer,sizeof(recv_buffer),0,(struct sockaddr *)&sour_addr,&sour_len);

//如果是數(shù)據(jù)包

if(TFTP_DATA==recv_buffer[1])

{

lastdata = MAKEWORD(recv_buffer[3],recv_buffer[2]); //塊號

//如果塊號正確

if(lastdata == blocknum)

{

//發(fā)送ACK包

len = makeack(blocknum,send_buffer,sizeof(send_buffer));

sendto(sock,send_buffer,len,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));

blocknum++;

if(blocknum > 65535)

blocknum = 0;

//最后一包

if(ret < TFTP_NOTEND_DATALEN)

{

//寫入文件

fwrite(&recv_buffer[4],1,ret-4,file);

flen = flen + ret -4;

#ifdef _DEBUG_

printf("%s %s %dn", __FILE__, __FUNCTION__, __LINE__);

printf("*****傳輸結(jié)束,共收到 %d 字節(jié)*****n",flen);

#endif

rewind(file);

if((decrypt_file =fopen("decrypt_temp","wb+"))==NULL){

printf("decrypt file open error n");

return;

}

decrypt(file, decrypt_file);

fclose(decrypt_file);

rename("decrypt_temp", filename);

fclose(file);

record(2,&sour_addr,filename);

return;

}

else

{

fwrite(&recv_buffer[4],1,512,file);

flen = flen + 512;

#ifdef _DEBUG_

printf("%s %s %dn", __FILE__, __FUNCTION__, __LINE__);

printf("已收到 %d 字節(jié)n",flen);

#endif

}

}

else

{

//重新發(fā)送ACK包

printf("數(shù)據(jù)包塊號錯誤.n");

sendto(sock,send_buffer,len,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));

}

}

}

}

}

}

}

C)客戶端與服務(wù)都配有工程管理器,可通過make 完成編譯。

D)實現(xiàn)效果:





本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉