DNSがどのように機能するかについての論文を書き、Pythonで小さいながらも機能するDNSサーバーを構築する必要があります。
私は次のようにパケットが受信されたときにスレッドを開く単純なUDPソケットサーバーを持っています:
while 1:
try:
stream, addr = serversocket.recvfrom(buffr)
threading.Thread(target=handler, args=(stream, addr, threading.activeCount(),)).start()
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
except_catch(exc_type.__name__, exc_value, exc_traceback, threading.current_thread().name)
ハンドラー関数は、メモリ内で要求されたレコードを見つけようとするだけで、見つからない場合は、別のサーバーでDNSクエリを実行する別の関数を実行して、レコードがない場合はレコードをフェッチします。これはややフェイルセーフであり、私の問題はどこにありますか。
def dnsrn(ip, type):
try:
mkr = dns.resolver.Resolver()
mkr.nameservers = ['192.168.0.1']
res = mkr.query(ip, type)
for rdata in res:
return rdata.address # this works for A records
# to do for other types of records
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
except_catch(exc_type.__name__, exc_value, exc_traceback, threading.current_thread().name)
ご覧のとおり、まだ完成していませんが、すでに問題があります。場合によっては、この関数が渡され、エラーログにエラーが発生しない限りスレッドが終了しないことがあります。私はテストしましたが、エラーログには子がスローしたすべてのエラーが記録されているはずです。私は、設定された時間ごとに一連のプリセットからランダムな要求を送信するようにプログラムされた単純なクライアントを持っていますが、子供がハングするときのパターンはないようです。約24時間のテストの後、約1〜3個のゾンビスレッドが残ります。
疑問に思っている場合は、これが例外関数のようになります。
def except_catch(type, value, track, thread=None):
if type != "SystemExit":
import traceback
rawreport = traceback.format_exception(type, value, track)
report = "\n" . join(rawreport)
errorlog = open(error_log_path + "/errors.log", "a")
if thread != None:
errorlog.write("Exception in thread: " + thread + "\n\n")
errorlog.write(("%s\n" + "-" * 30 + "\n\n") % report)
errorlog.close()
sys.excepthook = except_catch