(PHP 4, PHP 5, PHP 7, PHP 8)
fsockopen — 打開(kāi)一個(gè)網(wǎng)絡(luò)連接或者一個(gè)Unix套接字連接
$hostname
,$port
= -1,&$errno
= ?,&$errstr
= ?,$timeout
= ini_get("default_socket_timeout")
初始化一個(gè)套接字連接到指定主機(jī)(hostname
)。
PHP支持以下的套接字傳輸器類(lèi)型列表 所支持的套接字傳輸器(Socket Transports)列表。也可以通過(guò)stream_get_transports()來(lái)獲取套接字傳輸器支持類(lèi)型。
默認(rèn)情況下將以阻塞模式開(kāi)啟套接字連接。當(dāng)然你可以通過(guò)stream_set_blocking()將它轉(zhuǎn)換到非阻塞模式。
stream_socket_client()與之非常相似,而且提供了更加豐富的參數(shù)設(shè)置,包括非阻塞模式和提供上下文的的設(shè)置。
hostname
如果安裝了OpenSSL,那么你也許應(yīng)該在你的主機(jī)名地址前面添加訪問(wèn)協(xié)議ssl://
或者是tls://
,從而可以使用基于TCP/IP協(xié)議的SSL或者TLS的客戶端連接到遠(yuǎn)程主機(jī)。
port
端口號(hào)。如果對(duì)該參數(shù)傳一個(gè)-1,則表示不使用端口,例如unix://
。
errno
如果傳入了該參數(shù),holds the system level error number that occurred in the
system-level connect()
call。
如果errno
的返回值為0
,而且這個(gè)函數(shù)的返回值為false
,那么這表明該錯(cuò)誤發(fā)生在套接字連接(connect()
)調(diào)用之前,導(dǎo)致連接失敗的原因最大的可能是初始化套接字的時(shí)候發(fā)生了錯(cuò)誤。
errstr
錯(cuò)誤信息將以字符串的信息返回。
timeout
設(shè)置連接的時(shí)限,單位為秒。
注意:
注意:如果你要對(duì)建立在套接字基礎(chǔ)上的讀寫(xiě)操作設(shè)置操作時(shí)間設(shè)置連接時(shí)限,請(qǐng)使用stream_set_timeout(),fsockopen()的連接時(shí)限(
timeout
)的參數(shù)僅僅在套接字連接的時(shí)候生效。
fsockopen()將返回一個(gè)文件句柄,之后可以被其他文件類(lèi)函數(shù)調(diào)用(例如:fgets(),fgetss(),fwrite(),fclose()還有feof())。如果調(diào)用失敗,將返回false
。
如果主機(jī)(hostname
)不可訪問(wèn),將會(huì)拋出一個(gè)警告級(jí)別(E_WARNING
)的錯(cuò)誤提示。
版本 | 說(shuō)明 |
---|---|
4.3.0 |
在win32系統(tǒng)上增加了對(duì)時(shí)限設(shè)置(timeout )參數(shù)的支持。
|
4.3.0 | 在TCP/IP協(xié)議的基礎(chǔ)上增加了SSL和TLS。 |
示例 #1 fsockopen()的例子
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
示例 #2 使用UDP連接
下面這個(gè)例子展示了怎么樣在自己的機(jī)器上通過(guò)UDP套接字連接(端口號(hào)13)來(lái)檢索日期和時(shí)間。
<?php
$fp = fsockopen("udp://127.0.0.1", 13, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr<br />\n";
} else {
fwrite($fp, "\n");
echo fread($fp, 26);
fclose($fp);
}
?>
注意:
因?yàn)榄h(huán)境的不同,某些情況下在Unix套接字連接或者自定義的連接設(shè)置連接時(shí)限(
timeout
)可能不會(huì)生效。
UDP套接字有些時(shí)候在即使遠(yuǎn)程主機(jī)未知的情況,也能打開(kāi),并且不發(fā)生任何錯(cuò)誤。只有當(dāng)你通過(guò)該套接字進(jìn)行讀寫(xiě)的時(shí)候才會(huì)發(fā)現(xiàn)錯(cuò)誤。之所以會(huì)這樣,是因?yàn)閁DP是一個(gè)“非連接狀態(tài)”的協(xié)議,那么這就意味著當(dāng)前操作系統(tǒng)直到它(套接字)真正需要發(fā)送和接受數(shù)據(jù)的時(shí)候才會(huì)去嘗試為其去建立連接。
注意: 當(dāng)指定數(shù)值型的 IPv6 地址(例如
fe80::1
)時(shí)必須用方括號(hào)將 IP 圍起來(lái)——例如,tcp://[fe80::1]:80
。