Python網絡編程筆記(三):套接字名和DNS

套接字名

域名服務(DNS, Domain Name Service): 域名和真實IP地址的映射尚揣。

套接字的5個坐標

  • 地址族(Adress Family),比如 AF_INET, AF_UNIX
  • 套接字類型(Socket Type), 比如SOCK_DGRAM, SOCK_STREAM
  • 協議 (protocol), 前兩個確定后協議可選很少求豫,所以一般不寫,或者寫0反肋,表示自動選擇七咧,比如IPPROTO_TCP, IPPROTO_UDP
  • 主機名
  • 端口號

IPV6的特殊情況:
IPV6中套接字名不止包括主機名、端口號靶庙,還包括“流”信息问畅,“范圍”標識等額外坐標。

現代地址解析-getaddrinfo()的使用

套接字需要的5個坐標都可以得到六荒。生產環(huán)境代碼很少使用 AF_INET 這類socket模塊的常量护姆,采用的是 getaddrinfo()

>>> from pprint import pprint // 打印元組列表好看
// 調用
>>> infolist = socket.getaddrinfo('gatech.edu', 'www')
// 等同于
>>> infolist = socket.getaddrinfo('gatech.edu', 80)
// 返回
>>> pprint(infolist)
[(2, 1, 6, '', ('130.208.77.55', 80)),
 (2, 2, 17, '', ('130.208.77.55', 80)]
>>> info = infolist[0]
// 元組前三項分別為地址族、套接字類型掏击、協議卵皂,用來初始化套接字
>>> s = socket.socket(*info[0:3])
// 元組第5項為(主機名,端口), 可用來調用
>>> s.connect(info[4])

使用 getaddrinfo() 為服務器綁定端口

參數:getaddrinfo(host, port, address_family, sock_type, protocl, flag) 如果某個字段為數字砚亭,可以使用0代表通配符

場景:正在創(chuàng)建套接字或者希望客戶端從一個可預計的地址連接至其他主機, 需要bind()灯变。

用法:把主機名設為 None, 127.0.0.1, localhost等殴玛,提供端口號、套接字類型等柒凉。

>>> from socket import getaddrinfo
// 想用 TCP 來支持 smtp 數據傳輸的話族阅,應該通過 bind() 把套接字綁定到哪個地址
>>> getaddrinfo(None, 'smtp', 0, socket.SOCK_STREAM, 0, socket.AI_PSASSIVE)
// 返回告訴我們可以bind到本機的任何IPV4或IPV6地址
[(2, 1, 6, '', ('0.0.0.0', 25)), (10, 1, 6, '', ('::', 25, 0, 0))]

使用 getaddrinfo() 連接服務

場景:connect()sendto()

參數:

  1. AI_ADDRCONFIG 標記: 過濾計算機無法連接的地址
  2. AI_V4MAPPED 標記:本機只有IPV6,但是連接的服務只支持IPV4膝捞,指定后坦刀,會將服務的IPV4地址編碼為可用的IPV6地址。

用法:

>>> getaddrinfo('ftp.kernel.org', 'ftp', 0, socket.SOCK_STREAM, 0,
...           socket.AI_ADDRCONFIG | socket.AI_V4MAPPED)
[(2, 1, 6, '', ('204.13.33.3', 21)),
 (2, 1, 6, '', ('204.13.33.4', 21)]

返回的列表是有順序的蔬咬,經過了負載均衡鲤遥,一般選擇第一個。

使用 getaddrinfo() 請求規(guī)范主機名

反向DNS查詢:IP映射到主機名林艘。

風險:

  1. IP地址擁有者可以隨意設置主機名盖奈。因此要驗證。
  2. 耗時狐援。

用法:設置 AI_CANNONNAME 標志, 返回項第四項為規(guī)范主機名钢坦。

其他 getaddrinfo() 標記

總結下之前的:

  • AI_PASSIVE 標記:被動的,用于 bind()啥酱,節(jié)點為null時爹凹,返回通配地址,否則返回回環(huán)地址镶殷。
  • AI_ADDRCONFIG 標記: 過濾計算機無法連接的地址
  • AI_V4MAPPED 標記:本機只有IPV6禾酱,但是連接的服務只支持IPV4,指定后绘趋,會將服務的IPV4地址編碼為可用的IPV6地址颤陶。
  • AI_CANNONNAME 標記, 返回項第四項為規(guī)范主機名。

其他:

  • AI_ALL: 與 AI_V4MAPPED 結合使用陷遮,表示包含已知的與目標主機的所有地址滓走。
  • AI_NUMERICHOST: 調用的節(jié)點名必須是 IPV4 或者 IPV6 地址,不是字符串
  • AI_NUMRICSERV: 禁用"www"這種端口帽馋,只用"80"這種闲坎。

getaddrinfo() 之前經常使用的原始名稱服務程序

// 返回主機名
socket.gethostname()
socket.getfqdn()

// 對IPV4主機名和IP地址互換
socket.gethostbyname('cern.h')
socket.gethostbyaddr('128.189.22.1')

// 查詢協議號和端口號
>>> socket.getprotobyname('UDP')
17
>>> socket.getservbyname('www')
80
>>> socket.getservbyport(80)
'www'

// 獲取機器主IP地址
socket.gethostbyname(socket.getfqdn())
// 調用都可能失敗,要做好二手準備茬斧。

代碼

// 使用 `getaddrinfo()`創(chuàng)建并連接套接字

#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter04/www_ping.py
# Find the WWW service of an arbitrary host using getaddrinfo().

import argparse, socket, sys

def connect_to(hostname_or_ip):
    try:
        infolist = socket.getaddrinfo(
            hostname_or_ip, 'www', 0, socket.SOCK_STREAM, 0,
            socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME,
            )
    // getaddrinfo失敗后特殊錯誤 gaierror
    except socket.gaierror as e:
        print('Name service failure:', e.args[1])
        sys.exit(1)

    info = infolist[0]  # per standard recommendation, try the first one
    socket_args = info[0:3]
    address = info[4]
    s = socket.socket(*socket_args)
    try:
        s.connect(address)
    except socket.error as e:
        print('Network failure:', e.args[1])
    else:
        print('Success: host', info[3], 'is listening on port 80')

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Try connecting to port 80')
    parser.add_argument('hostname', help='hostname that you want to contact')
    connect_to(parser.parse_args().hostname)

DNS 協議

  • 目的:解析主機名腰懂,返回IP地址
  • 標準:RFC 1034和 RFC 1035
  • 傳輸層協議:UDP/IP 與 TCP/IP
  • 端口號:53
  • 庫:第三方,包括 dnspython3

DNS查詢只有在緩存项秉、多播DNS等失敗后才會啟動DNS服務器绣溜,畢竟這很耗時。

使用 Python 進行 DNS 查詢

// 一個包含遞歸的簡單 DNS 查詢
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter04/dns_basic.py
# Basic DNS query

import argparse, dns.resolver

def lookup(name):
    for qtype in 'A', 'AAAA', 'CNAME', 'MX', 'NS':
        answer = dns.resolver.query(name, qtype, raise_on_no_answer=False)
        if answer.rrset is not None:
            print(answer.rrset)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Resolve a name using DNS')
    parser.add_argument('name', help='name that you want to look up in DNS')
    lookup(parser.parse_args().name)

answer.rrset返回格式:查詢名稱娄蔼,有效時間怖喻,類型(IN, 表示互聯網地址響應), 記錄的類型qtype(A: IPV4, AAAA: IPV6, NS: name service, MX: 郵件服務器)

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末底哗,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子锚沸,更是在濱河造成了極大的恐慌跋选,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哗蜈,死亡現場離奇詭異前标,居然都是意外死亡,警方通過查閱死者的電腦和手機距潘,發(fā)現死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門炼列,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人音比,你說我怎么就攤上這事俭尖。” “怎么了洞翩?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵稽犁,是天一觀的道長。 經常有香客問我骚亿,道長缭付,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任循未,我火速辦了婚禮,結果婚禮上秫舌,老公的妹妹穿的比我還像新娘的妖。我一直安慰自己,他們只是感情好足陨,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布嫂粟。 她就那樣靜靜地躺著,像睡著了一般墨缘。 火紅的嫁衣襯著肌膚如雪星虹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天镊讼,我揣著相機與錄音宽涌,去河邊找鬼。 笑死蝶棋,一個胖子當著我的面吹牛卸亮,可吹牛的內容都是我干的。 我是一名探鬼主播玩裙,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼兼贸,長吁一口氣:“原來是場噩夢啊……” “哼段直!你這毒婦竟也來了?” 一聲冷哼從身側響起溶诞,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤鸯檬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后螺垢,有當地人在樹林里發(fā)現了一具尸體喧务,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年甩苛,在試婚紗的時候發(fā)現自己被綠了蹂楣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡讯蒲,死狀恐怖痊土,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情墨林,我是刑警寧澤赁酝,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站旭等,受9級特大地震影響酌呆,放射性物質發(fā)生泄漏。R本人自食惡果不足惜搔耕,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一隙袁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弃榨,春花似錦菩收、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至官辈,卻和暖如春箱舞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拳亿。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工晴股, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肺魁。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓队魏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胡桨,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容