我們最近遇到了類似於您的問題。我們發現file_get_contents()
最終調用getaddrinfo()
,它實現RFC3484的一些排序算法。
從php source code
PHPAPI int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, zend_string **error_string)
{
// skip...
if ((n = getaddrinfo(host, NULL, &hints, &res))) {
if (error_string) {
*error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n));
php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string));
} else {
php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n));
}
return 0;
}
//skip...
}
這件作品片段的我們仍然搞清楚什麼是更好的方法來處理這個問題。
編輯:
RFC3484的第6節指定目標地址選擇算法,以及第9條有關的IPv4。
規則9:使用最長的匹配前綴。
當DA和DB屬於同一地址族(均爲IPv6或 都是IPv4)的:如果CommonPrefixLen(DA,來源(DA))> CommonPrefixLen(DB,來源(DB)),然後喜歡DA 。類似地,如果CommonPrefixLen(DA,Source(DA))< CommonPrefixLen(DB,Source(DB)), 則優選DB。
假設我們擁有源地址192.168.1.100/24
和四個候選目的地地址192.168.1.33/24
,192.168.1.44/24
,192.168.2.55/24
,192.168.2.66/24
。
以二進制格式
S 192.168.1.100 11000000.10101000.00000001.01100100
-------------------------------------------------------
DA 192.168.1.33 11000000.10101000.00000001.00100001
DB 192.168.1.44 11000000.10101000.00000001.00101100
DC 192.168.2.55 11000000.10101000.00000010.00110111
DD 192.168.2.66 11000000.10101000.00000010.01000010
表示上述地址你可以看到,
CommonPrefixLen(DA, S) == CommonPrefixLen(DB, S) == 25 >
CommonPrefixLen(DC, S) == CommonPrefixLen(DD, S) == 22
所以DA
或DB
,以先到者爲準在原來的DNS查詢,將被選爲最終目的地glibc
執行。
難道它之間有一個網絡代理? – mbs
緩存DNS查找。你必須清空系統的DNS緩存。 – Fracsi