麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Unix > 正文

UNIX網絡編程讀書筆記:名字與地址轉換

2024-06-28 13:27:25
字體:
來源:轉載
供稿:網友
UNIX網絡編程讀書筆記:名字與地址轉換紅心概述

在名字和數值地址間進行轉換的函數:

燈泡gethostbyname和gethostbyaddr:在主機名字與ipv4地址之間進行轉換。僅僅支持IPv4.

燈泡getservbyname和getservbyport:在服務名字和端口號之間進行轉換。

燈泡getaddrinfo和getnameinfo:用于主機名字和IP地址之間以及服務名字和端口號之間的轉換。(這兩個函數是協議無關的)

紅心域名系統

域名系統(Domain Name System,簡稱DNS)主要用于主機名字和IP地址之間的映射。

燈泡資源記錄

DNS中的條目稱為資源記錄(resource record,簡稱RR)。

RR類型:

A          A記錄把一個主機名映射成一個32位的IPv4地址。

AAAA    AAAA記錄把一個主機名映射成一個128位的IPv6地址。

PTR      稱為“指針記錄(pointer record)”,它把IP地址映射成主機名。

燈泡解析器和名字服務器

每個組織機構往往運行一個或多個名字服務器(name server),它們通常就是所謂的BIND(Berkeley Internet Name Domain)程序。應用程序通過調用稱為解析器(resolver)的函數庫中的函數接觸DNS服務器。常見的解析器函數是gethostbyname和gethostbyaddr:前者把主機名映射成IPv4地址,后者則執行相反的映射。

下圖展示了應用進程、解析器和名字服務器之間的一個典型關系。

image

解析器代碼通過讀取其系統相關配置文件確定本組織機構的名字服務器們(為可靠和冗余的目的,大多數組織機構運行多個名字服務器)的所在位置。文件/etc/resolv.conf通常包含本地名字服務器主機的IP地址。

燈泡DNS替代方法

不使用DNS也可能獲取名字和地址信息。常用的替代方法有靜態主機文件(通常是/etc/hosts文件)、網絡信息系統(Network Information System,簡稱NIS)以及輕權目錄訪問協議(Lightweight Directory access PRotocol,簡稱LDAP)。

紅心gethostbyname函數

查找主機名最基本的函數是gethostbyname。如果調用成功,它就返回一個指向hostent結構的指針,該結構中含有所查找主機的所有IPv4地址。這個函數的局限是只能返回IPv4地址,而getaddrinfo函數能夠同時處理IPv4地址和IPv6地址。

#include <netdb.h>struct hostent *gethostbyname(const char *hostname);返回值:非空指針——成功;空指針——出錯,同時設置h_errno

本函數返回的非空指針指向如下的hostent結構:

struct hostent {    char      *h_name;          /* official(canonical) name of host */    char     **h_aliases;       /* pointer to array of pointers to alias names */    int        h_addrtype;      /* host address type: AF_INET */    int        h_length;        /* length of address: 4 */        char     **h_addr_list;     /* ptr to array of ptrs with IPv4 addrs */};

image

gethostbyname與其他套接口函數的不同之處在于:當發生錯誤時,它不設置errno變量,而是將全局整數變量h_errno設置在頭文件<netdb.h>中定義的下列常值之一:

燈泡HOST_NOT_FOUND

燈泡TRY_AGAIN

燈泡NO_RECOVERY

燈泡NO_DATA(等同于NO_ADDRESS)

多數解析器提供名為hstrerror的函數,它以某個h_errno值作為唯一的參數,返回的是一個const char *指針,指向相應錯誤的說明。

紅心gethostbyaddr函數

gethostbyaddr函數試圖由一個二進制IP地址找到相應的主機名,與gethostbyname的行為剛好相反。

#include <netdb.h>struct hostent *gethostbyaddr(const char *addr, socklen_t len, int family);返回值:非空指針——成功;空指針——出錯,同時設置h_errno

本函數返回一個同樣指向hostent結構的指針。

addr參數實際上不是char *類型,而是一個指向存放IPv4地址的某個in_addr結構的指針;

len參數是這個結構的大?。簩τ贗Pv4地址為4;

family參數為AF_INET。

紅心getservbyname函數

服務也通??棵謥碚J知。如果我們在程序代碼中通過其名字而不是端口號來指代一個服務,而且從名字到端口號的映射關系保存在一個文件中(通常是/etc/services),那么即使端口號發生變動,我們需修改的僅僅是/etc/services文件中的某一行,而不必重新編譯應用程序。

getservbyname函數用于根據給定的名字查找相應服務。

#include <netdb.h>struct servent *getservbyname(const char *servname, const char *protoname);返回:非空指針——成功;空指針——出錯

本函數返回的非空指針指向如下的servent結構:

struct servent {    char     *s_name;         /* official service name */    char    **s_aliases;      /* alias list */    int       s_port;         /* port number, network-byte order */    char     *s_proto;        /* protocol to use */};

服務名參數servname必須指定。如果同時指定了協議(即protoname參數為非空指針),那么指定服務必須有匹配的協議。有些因特網服務既用TCP也用UDP提供(例如DNS),其他因特網服務則僅僅支持單個協議(例如FTP要求使用TCP)。如果protoname未指定而servname指定服務支持多個協議,那么返回哪個端口號取決于實現。

servent結構中我們關心的主要是端口號。既然端口號是以網絡字節序返回的,把它存放到套接口地址結構時絕不能調用htons。

本函數的典型調用如下:

struct servent *sptr;sptr = getservbyname("domain", "udp");sptr = getservbyname("ftp", "tcp");
紅心getservbyport函數

getservbyport函數用于根據給定端口號和可選協議查找相應服務。

#include <netdb.h>struct servent *getservbyport(int port, const char *protoname);返回:非空指針——成功;空指針——出錯

port參數的值必須為網絡字節序。本函數的典型調用如下:

struct servent *sptr;sptr = getservbyport(htons(53), "udp");sptr = getservbyport(htons(21), "tcp");
紅心getaddrinfo函數

getaddrinfo函數能夠處理名字到地址以及服務到端口這兩種轉換,它解決了把主機名和服務名轉換成套接口地址結構的問題,返回的是一個sockaddr結構的鏈表而不是一個地址清單。這些sockaddr結構隨后可由套接口函數直接使用。

#include <netdb.h>int  getaddrinfo(const char *hostname, const char *service,                 const struct addrinfo *hints, struct addrinfo **result);返回:0——成功;非0——出錯

本函數通過result指針參數返回一個指向addrinfo結構鏈表的指針,而addrinfo結構定義在頭文件<netdb.h>中:

struct addrinfo {    int                  ai_flags;         /* AI_PASSIVE, AI_CANONNAME */    int                  ai_family;        /* AF_xxx */    int                  ai_socktype;      /* SOCK_xxx */    int                  ai_protocol;      /* 0 or IPPROTO_xxx for IPv4 and IPv6 */    socklen_t            ai_addrlen;       /* length of ai_addr */    char                *ai_canonname;     /* ptr to canonical name for host */    struct sockaddr     *ai_addr;          /* ptr to socket address structure */    struct addrinfo     *ai_next;          /* ptr to next structure in linked list */};

其中,

hostname參數是一個主機名或地址串(IPv4的點分十進制數串或IPv6的十六進制數串)。

service參數是一個服務名或十進制端口號數串。

hints參數可以是一個空指針,也可以是一個指向某個addrinfo結構的指針,調用者在這個結構中填入關于期望返回的信息類型的暗示。

hints結構中調用者可以設置的成員有:

  • ai_flags(零個或多個在一起的AI_xxx值)
  • ai_family(某個AF_xxx值)
  • ai_socktype(某個SOCK_xxx值)
  • ai_protocol

其中ai_flags成員可用的標志值及其含義如下:

燈泡AI_PASSIVE  套接口將用于被動打開。

燈泡AI_CANONNAME  告知getaddrinfo函數返回主機的規范名字。

燈泡AI_NUMERICHOST  防止任何類型的名字到地址映射;hostname參數必須是一個地址串。

燈泡AI_NUMERICSERV  防止任何類型的名字到服務映射;service參數必須是一個十進制端口號數串。

燈泡AI_V4MAPPED  如果同時指定ai_family成員的值為AF_INET6, 那么如果沒有可用的AAAA記錄,就返回與A記錄對應的IPv4映射的IPv6地址。

燈泡AI_ALL  如果同時指定AI_V4MAPPED標志,那么除了返回與AAAA記錄對應的IPv6地址外,還返回與A記錄對應的IPv4映射的IPv6地址。

燈泡AI_ADDRCONFIG  按照所在主機的配置選擇返回地址類型,也就是只查找與所在主機回饋接口以外的網絡接口配置的IP地址版本一致的地址。

如果hints參數是一個空指針,本函數就假設ai_flags、ai_sokctype和ai_protocol的值均為0,ai_family的值為AF_UNSPEC。

如果本函數返回成功(0),那么由result參數指向的變量已被填入一個指針,它指向的是由其中的ai_next成員串接起來的addrinfo結構鏈表。可導致返回多個addrinfo結構的情形有以下兩個:

燈泡如果與hostname參數關聯的地址有多個,那么適用于所請求地址族(可通過hints結構的ai_family成員設置)的每個地址都返回一個對應的結構。

燈泡如果service參數指定的服務支持多個套接口類型,那么每個套接口類型都可能返回一個對應的結構,具體取決于hints結構的ai_socktype成員。

紅心getnameinfo函數

getnameinfo是getaddrinfo的互補函數:它以一個套接口地址為參數,返回描述其中的主機的一個字符串和描述其中的服務的另一個字符串。本函數以協議無關的方式提供這些信息;也就是說,調用者不必關心存放在套接口地址結構中的協議地址的類型。

#include <netdb.h>int getnameinfo(const struct sockaddr *sockaddr, socklen_t addrlen,                char *host, socklen_t hostlen,                char *serv, socklen_t servlen, int flags);返回:0——成功,非0——出錯

sockaddr指向一個套接口地址結構。

待返回的2個直觀可讀的字符串由調用者預先分配存儲空間:host和hostlen指定主機字符串;serv和servlen指定服務字符串。如果調用者不想返回主機字符串,那就指定hostlen為0。同樣,把servlen指定為0就是不想返回服務字符串。頭文件<netdb.h>中定義了2個常值用于分配這兩個存儲空間:NI_MAXHOST給出主機字符串存儲空間的最大長度,值為1025;NI_MAXSERV給出服務字符串存儲空間的最大長度,值為32.

6個可指定的標志flags,用于改變getnameinfo的操作:

常值 說明
NI_DGRAM NI_NAMEREQD NI_NOFQDN NI_NUMERICHOST NI_NUMERICSCOPE NI_NUMERICSERV 數據報服務 若不能從地址解析出名字則返回錯誤 只返回FQDN的主機名部分 以數串格式返回主機字符串 以數串格式返回范圍標識字符串 以數串格式返回服務字符串

 

四類網絡相關信息總結如下表:

信息 數據文件 結構 鍵值查找函數
主機 網絡 協議 服務 /etc/hosts /etc/networks /etc/protocols /etc/services hostent netent protoent servent gethostbyaddr,gethostbyname getnetbyaddr,getnetbyname getprotobyname,getprotobynumber getservbyname,getservbyport

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广州毛片| h色在线观看 | 精品乱码久久久久 | xnxx 日本19 | 国产一区二区精品免费 | 91成| 国产成人精品一区二区仙踪林 | 欧美日韩综合视频 | 久久久久久久久久久国产精品 | 美女视频在线观看黄 | 国产一级一国产一级毛片 | 久久精品网站视频 | 久久精品超碰 | 斗破苍穹在线观看免费完整观看 | www.48xx.com| 久草视频手机在线观看 | 国产一级毛片国语版 | 国产亚洲欧美日韩高清 | 日韩视频在线视频 | 久久久久久久久久一本门道91 | 欧美特级一级毛片 | 国产精品免费久久久久 | 一级大黄毛片 | 蜜桃欧美性大片免费视频 | 国产午夜网 | 免费毛片电影 | 亚洲午夜在线视频 | 国产欧美一区二区三区免费看 | 亚洲网站免费观看 | 成人黄色网战 | 成人精品一区二区三区中文字幕 | 国产免费永久在线观看 | 一级黄色片在线看 | 国产精品www | 性盈盈盈影院 | 国产羞羞视频在线观看免费应用 | 日本成年免费网站 | 午夜视频在线免费播放 | 亚洲影视中文字幕 | 成人小视频在线播放 | 国产精品jk白丝蜜臀av软件 |