資源簡介
設計一個DNS服務器程序,讀入“域名-IP地址”對照表,當客戶端查詢域名對應的IP地址時,用域名檢索該對照表,三種檢索結果:
檢索結果為ip地址0.0.0.0,則向客戶端返回“域名不存在”的報錯消息(不良網站攔截功能)
檢索結果為普通IP地址,則向客戶返回這個地址(服務器功能)
表中未檢到該域名,則向因特網DNS服務器發出查詢,并將結果返給客戶端(中繼功能)
考慮多個計算機上的客戶端會同時查詢,需要進行消息ID的轉換
代碼片段和文件信息
#include?
#include?
#include??
#include??
#include??
#include?
#include?
#include?
#include?
using?namespace?std;
#pragma??comment(lib?“Ws2_32.lib“)?
#define?DEF_DNS_ADDRESS?“192.168.146.2“ //外部DNS服務器地址
#define?LOCAL_ADDRESS?“127.0.0.1“ //本地DNS服務器地址
#define?DNS_PORT?53 //進行DNS服務的53端口
#define?BUF_SIZE?512
#define?LENGTH?65
#define?AMOUNT?300
#define?NOTFOUND?-1
//DNS報文首部
typedef?struct?DNSHeader
{
????unsigned?short?ID;
????unsigned?short?Flags;
????unsigned?short?QuestNum;
????unsigned?short?AnswerNum;
????unsigned?short?AuthorNum;
????unsigned?short?AdditionNum;
}?DNSHDR?*pDNSHDR;
//DNS域名解析表結構
typedef?struct?translate
{
string?IP; //IP地址
string?domain; //域名
}?Translate;
//ID轉換表結構
typedef?struct?IDChange
{
unsigned?short?oldID; //原有ID
BOOL?done; //標記是否完成解析
SOCKADDR_IN?client; //請求者套接字地址
}?IDTransform;
Translate?DNS_table[AMOUNT]; //DNS域名解析表
IDTransform?IDTransTable[AMOUNT]; //ID轉換表
int?IDcount?=?0; //轉換表中的條目個數
char?url[LENGTH]; //域名
SYSTEMTIME?sys;?????????????????????//系統時間
int?Day?Hour?Minute?Second?Milliseconds;//保存系統時間的變量
//函數:獲取域名解析表
int?GetTable(char?*tablePath)
{
int?i=0?j?pos=0;
string?table[AMOUNT];
ifstream?infile(tablePath?ios::in); //以讀入方式打開文本文件
if(!?infile)?{
cerr?<“Open“?< exit(1);
}
//每次從文件中讀入一行,直至讀到文件結束符為止
while?(getline(infile?table[i])?&&?i? i++;
if?(i?==?AMOUNT-1)
cout?<“The?DNS?table?memory?is?full.?“?<
for?(j?=?0;?j? pos?=?table[j].find(‘?‘);
if?(pos?>?table[j].size())
cout?<“The?record?is?not?in?a?correct?format.?“?< else?{
DNS_table[j].IP?=?table[j].substr(0?pos);
DNS_table[j].domain?=?table[j].substr(pos+1);
}
}
infile.close(); //關閉文件
cout?<“Load?records?succeed.?“?<
return?i-1; //返回域名解析表中條目個數
}
//函數:獲取DNS請求中的域名
void?GetUrl(char?*recvbuf?int?recvnum)
{
char?urlname[LENGTH];
int?i?=?0?j?k?=?0;
memset(url?0?LENGTH);
memcpy(urlname?&(recvbuf[sizeof(DNSHDR)])?recvnum-16); //獲取請求報文中的域名表示
int?len?=?strlen(urlname);
//域名轉換
while?(i? if?(urlname[i]?>?0?&&?urlname[i]?<=?63)
for?(j?=?urlname[i]?i++;?j?>?0;?j--?i++?k++)
url[k]?=?urlname[i];
if?(urlname[i]?!=?0)?{
url[k]?=?‘.‘;
????k++;
}
}
url[k]?=?‘\0‘;
}
//函數:判斷是否在表中找到DNS請求中的域名,找到返回下標
int?IsFind(char*?url?int?num)
{
int?find?=?NOTFOUND;
char*?domain;
for?(int?i?=?0;?i? domain?=?(char?*)DNS_table[i].domain.c_str();
if?(strcmp(domain?url)?==?0)?{ //找到
find?=?i;
break;
}
}
return?find;
}
//函數:將請求ID轉換為新的ID,并將信息寫入ID轉換表中
unsigned?short?RegisterNewID?(unsigned?short?oID?SOCKADDR_IN?temp?BOOL?ifdone)
{
srand(time(NULL));
IDTransTable[IDcount].oldID?=?oID;
IDTransTable[IDcount].client?=?temp;
- 上一篇:北京郵電大學大三下計算機圖形學作業一
- 下一篇:操作系統實習-快速文件系統
評論
共有 條評論