# fsockopen

(PHP 4, PHP 5, PHP 7)

fsockopen — 打开一个网络连接或者一个Unix套接字连接

### 说明

fsockopen ( string `$hostname` [, int `$port` = -1 [, int `&$errno` [, string `&$errstr` [, float `$timeout` = ini_get("default_socket_timeout") ]]]] ) : resource

初始化一个套接字连接到指定主机（`hostname`）。

PHP支持以下的套接字传输器类型列表 所支持的套接字传输器（Socket Transports）列表。也可以通过stream_get_transports()来获取套接字传输器支持类型。

默认情况下将以阻塞模式开启套接字连接。当然你可以通过stream_set_blocking()将它转换到非阻塞模式。

stream_socket_client()与之非常相似，而且提供了更加丰富的参数设置，包括非阻塞模式和提供上下文的的设置。

### 参数

`hostname`

  如果安装了OpenSSL，那么你也许应该在你的主机名地址前面添加访问协议ssl://或者是tls://，从而可以使用基于TCP/IP协议的SSL或者TLS的客户端连接到远程主机。

`port`

  端口号。如果对该参数传一个-1，则表示不使用端口，例如unix://。

`errno`

  如果传入了该参数，holds the system level error number that occurred in the system-level connect() call。

  如果`errno`的返回值为0，而且这个函数的返回值为`FALSE`，那么这表明该错误发生在套接字连接（connect()）调用之前，导致连接失败的原因最大的可能是初始化套接字的时候发生了错误。

`errstr`

  错误信息将以字符串的信息返回。

`timeout`

  设置连接的时限，单位为秒。

  > Note:

  > 注意：如果你要对建立在套接字基础上的读写操作设置操作时间设置连接时限，请使用stream_set_timeout()，fsockopen()的连接时限（`timeout`）的参数仅仅在套接字连接的时候生效。

### 返回值

fsockopen()将返回一个文件句柄，之后可以被其他文件类函数调用（例如：fgets()，fgetss()，fwrite()，fclose()还有feof()）。如果调用失败，将返回`FALSE`。

### 错误／异常

如果主机（`hostname`）不可访问，将会抛出一个警告级别（`E_WARNING`）的错误提示。

### 更新日志

版本 | 说明
--- | ---
4.3.0 | 在win32系统上增加了对时限设置（`timeout`）参数的支持。
4.3.0 | 在TCP/IP协议的基础上增加了SSL和TLS。

### 范例

Example #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);
    }
    ?>

Example #2 使用UDP连接

下面这个例子展示了怎么样在自己的机器上通过UDP套接字连接（端口号13）来检索日期和时间。

    <?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);
    }
    ?>

### 注释

> Note:

> 因为环境的不同，某些情况下在Unix套接字连接或者自定义的连接设置连接时限（`timeout`）可能不会生效。

Warning

UDP套接字有些时候在即使远程主机未知的情况，也能打开，并且不发生任何错误。只有当你通过该套接字进行读写的时候才会发现错误。之所以会这样，是因为UDP是一个“非连接状态”的协议，那么这就意味着当前操作系统直到它（套接字）真正需要发送和接受数据的时候才会去尝试为其去建立连接。

> Note: 当指定数值型的 IPv6 地址（例如 fe80::1）时必须用方括号将 IP 围起来——例如， tcp://[fe80::1]:80。

### 参见

- pfsockopen() - 打开一个持久的网络连接或者Unix套接字连接。
- stream_socket_client() - Open Internet or Unix domain socket connection
- stream_set_blocking() - 为资源流设置阻塞或者阻塞模式
- stream_set_timeout() - Set timeout period on a stream
- fgets() - 从文件指针中读取一行
- fgetss() - 从文件指针中读取一行并过滤掉 HTML 标记
- fwrite() - 写入文件（可安全用于二进制文件）
- fclose() - 关闭一个已打开的文件指针
- feof() - 测试文件指针是否到了文件结束的位置
- socket_connect() - 开启一个套接字连接
- The Curl extension