# 3.4. IP 位址，續集

還好你運氣不錯，有一堆函式讓你能夠控制 IP address，而不需要親自用 long 與 << 運算符來處理它們。

咱們說，你有一個 struct sockaddr\_in ina，而且你有一個 "10.12.110.57" 或 "2001:db8:63b3:1::3490" 這樣的一個 IP address 要儲存。你想要使用 inet\_pton() 函式將 IP address 轉換為數值與句號的符號，並依照你指定的 AF\_INET 或 AF\_INET6 來決定要儲存在 struct in\_addr 或 struct in6\_addr。

（"pton" 的意思是 "presentation to network"，你可以稱之為 "printable to network"，如果這樣會比較好記的話）。

這樣的轉換可以用如下的方式：

```c
struct sockaddr_in sa; // IPv4
struct sockaddr_in6 sa6; // IPv6
inet_pton(AF_INET, "192.0.2.1", &(sa.sin_addr)); // IPv4
inet_pton(AF_INET6, "2001:db8:63b3:1::3490", &(sa6.sin6_addr)); // IPv6
```

（小記：原本的老方法是使用名為 inet\_addr() 或是 inet\_aton() 的函式；這些都過時了，而且不適合在 IPv6 中使用）。

目前上述的程式碼片段還不是很可靠，因為沒有錯誤檢查。inet\_pton() 在錯誤時會傳回 -1，而若位址被搞爛了，則會傳回 0。所以在使用之前要檢查，並確認結果是大於 0 的。

好了，現在你可以將 IP address 字串轉換為它們的二進位表示。

還有其它方法嗎？

如果你有一個 struct in\_addr 且你想要以數字與句號印出來的話呢？

（呵呵，或者如果你想要以＂十六進位與冒號＂印出 struct in6\_addr］。在這個例子中，你會想要使用 inet\_ntop()函式［"ntop" 意謂 "network to presentation"－如果有比較好記的話，你可以稱它為 "network to printable"），像是這樣：

```c
// IPv4:
char ip4[INET_ADDRSTRLEN]; // 儲存 IPv4 字串的空間
struct sockaddr_in sa; // 假裝這會由某個東西載入
inet_ntop(AF_INET, &(sa.sin_addr), ip4, INET_ADDRSTRLEN);
printf("The IPv4 address is: %s\n", ip4);
// IPv6:
char ip6[INET6_ADDRSTRLEN]; // 儲存 IPv6 字串的空間
struct sockaddr_in6 sa6; // 假裝這會由某個東西載入
inet_ntop(AF_INET6, &(sa6.sin6_addr), ip6, INET6_ADDRSTRLEN);
printf("The address is: %s\n", ip6);
```

當你呼叫它時，你會傳遞位址的型別（IPv4 或 IPv6），該位址是一個指向儲存結果的字串，與該字串的最大長度。「有兩個 macro（巨集）可以很方便地儲存你想儲存的最大 IPv4 或 IPv6 位址字串大小：INET\_ADDRSTRLEN 與 INET6\_ADDRSTRLEN」。

（另一個要再次注意的是以前的方法：以前做這類轉換的函式名為 inet\_ntoa()，它已經過期了，而也在 IPv6 中也不適用）。

最後，這些函式只能用在數值的 IP address 上，它們不需要 DNS nameserver 來查詢主機名稱，如 "[www.example.com"。你可以使用](http://www.example.com"。你可以使用) getaddrinfo() 來做這件事情，如同你稍後會看到的。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://beej-zhtw.netdpi.net/ipaddress_struct/ip_set.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
