fsockopen

(PHP 4、PHP 5、PHP 7、PHP 8)

fsockopen打开互联网或 Unix 域套接字连接

说明

fsockopen(
    字符串 $hostname,
    int $port = -1,
    int &$error_code = null,
    string &$error_message = null,
    ?float $timeout = null
): resource|false

启动到 hostname 指定的资源的套接字连接。

PHP 支持 Internet 和 Unix 域中的目标,如 受支持的套接字传输列表 中所述。还可以使用 stream_get_transports() 检索受支持的传输列表。

该套接字默认以阻塞模式打开。您可以使用 stream_set_blocking() 将其切换到非阻塞模式。

函数 stream_socket_client() 类似,但是提供了一组更丰富的选项,包括非阻塞连接和提供流上下文的能力。

参数

hostname

如果安装了 OpenSSL 支持 安装,您可以用 ssl://tls:// 指定 hostname 的前缀以使用 SSL 或 TLS 客户端连接通过 TCP/IP 连接到远程主机。

port

端口号。这可以省略并用 -1 跳过不使用端口的传输(例如 unix://)。

error_code

如果提供,则保留系统级 connect() 调用中发生的系统级错误号。

如果 error_code 中返回的值为 0 且函数返回 false,这表示错误发生在 connect() 调用之前。这最可能是由于初始化套接字的问题。

error_message

错误信息,类型为字符串。

timeout

连接超时(以秒为单位)。如果为 null,则使用 default_socket_timeout php.ini 设置。

注意:

如果您需要为通过套接字读取/写入数据设置一个过期时间,请使用 stream_set_timeout() 因为 fsockopen() 中的 timeout 参数在连接套接字时才会运行。

返回值

fsockopen() 返回一个文件指针,可将其与其他文件函数(例如 fgets()fgetss()fwrite()fclose()feof())一起使用。如果调用失败,它将返回 false

错误/异常

如果 hostname 不是有效的域名,则抛出 E_WARNING

更新日志

版本 说明
8.0.0 timeout 现在可为 null。

示例

示例 #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 连接

以下示例展示了如何在自己的计算机中从 UDP 服务“daytime”(端口 13)检索日期和时间。

<?php
$fp
= fsockopen("udp://127.0.0.1", 13, $errno, $errstr);
if (!
$fp) {
echo
"错误: $errno - $errstr<br />\n";
} else {
fwrite($fp, "\n");
echo
fread($fp, 26);
fclose($fp);
}
?>

注意

注意:

根据环境,Unix 域或可选的连接超时可能不可用。

警告

UDP 套接字有时会显示为已在没有错误的情况下打开,即使远程主机无法访问。只有当您读写套接字的数据时,错误才会出现。原因是因为 UDP 是个“无连接”协议,这意味着操作系统不会尝试在套接字需要发送或接收数据之前建立一个链接。

注意当指定一个数值 IPv6 地址(例如 fe80::1),您必须将 IP 放入方括号内——例如,tcp://[fe80::1]:80

另请参阅

添加注释

用户贡献注释 42 条注释

23
joe at edwardsconsultants dot com
21 年前
只给尝试使用 https 并认为他们必须采用 curl 或备用方法的用户留一个简短的注释 -
你可以使用 fsockopen,只需仔细阅读文档即可。基本上,他们正在说对于 HTTPS(SSL)网络请求应该使用“ssl://”。

因此,对于 authorize.net 及其他,甚至对于 PayPal IPN,这将适用;然而,我认为最好离开网站并解决 PayPal 的表单

<?php
$host
= "something.example.com";
$port = 443;
$path = "/the/url/path/file.php"; //or .dll, etc. for authnet, etc.

//you will need to setup an array of fields to post with
//then create the post string
$formdata = array ( "x_field" => "somevalue");
//build the post string
foreach($formdata AS $key => $val){
$poststring .= urlencode($key) . "=" . urlencode($val) . "&";
}
// strip off trailing ampersand
$poststring = substr($poststring, 0, -1);

$fp = fsockopen("ssl://".$host, $port, $errno, $errstr, $timeout = 30);

if(!
$fp){
//error tell us
echo "$errstr ($errno)\n";

}else{

//send the server request
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($poststring)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $poststring . "\r\n\r\n");

//loop through the response from the server
while(!feof($fp)) {
echo
fgets($fp, 4096);
}
//close fp - we are done with it
fclose($fp);
}
?>
16
sir_reality2001 at yahoo dot com
20 年前
<?php
// This script is an example of posting multiple files using
// fsockopen.
// The tricky part is making sure the HTTP headers and file boundaries are acceptable to the target webserver.
// This script is for example purposes only and could/should be improved upon.

$host='targethost';
$port=80;
$path='/test/socket/file_upload/receive_files.php';

// the file you want to upload
$file_array[0] = "dingoboy.gif"; // the file
$file_array[1] = "dingoboy2.gif"; // the file
$file_array[2] = "dingoboy3.gif"; // the file
$content_type = "image/gif"; // the file mime type
//$content_type = "text/plain";
//echo "file_array[0]:$file_array[0]<br><br>";

srand((double)microtime()*1000000);
$boundary = "---------------------------".substr(md5(rand(0,32000)),0,10);

$data = "--$boundary";

for(
$i=0;$i<count($file_array);$i++){
$content_file = join("", file($file_array[$i]));

$data.="
Content-Disposition: form-data; name=\"file"
.($i+1)."\"; filename=\"$file_array[$i]\"
Content-Type:
$content_type

$content_file
--
$boundary";

}

$data.="--\r\n\r\n";

$msg =
"POST $path HTTP/1.0
Content-Type: multipart/form-data; boundary=
$boundary
Content-Length: "
.strlen($data)."\r\n\r\n";

$result="";

// open the connection
$f = fsockopen($host, $port);

fputs($f,$msg.$data);

// get the response
while (!feof($f)) $result .= fread($f,32000);

fclose($f);

?>
11
ryan1_00 at hotmail dot com
17 年前
此脚本检查特定端口,所以你要在服务器上打开正确的端口才能使其运行。

例如,如果我有一个 Windows 域控制器且它正在提供 LDAP 服务,则会使用以下内容来检查它是否在线
<?php
chkServer
("MyDC", "389");
?>

对于 Web 服务器
<?php
chkServer
("MyWebSvr", "80");
?>

等等
--------------------------------------------------------

<?php
// 检查服务器是否处于连接至端口的状态
function chkServer($host, $port)
{
$hostip = @gethostbyname($host); // 从主机名解析 IP,失败时返回主机名

if ($hostip == $host) // 如果 IP 未解析
{
echo
"服务器已关闭或不存在";
}
else
{
if (!
$x = @fsockopen($hostip, $port, $errno, $errstr, 5)) // 尝试连接
{
echo
"服务器已关闭";
}
else
{
echo
"服务器已开启";
if (
$x)
{
@
fclose($x); //关闭连接
}
}
}
}
?>
4
michiel at parse dot nl
19 年前
以下代码片段允许你检索页面的标题。

非常适合重写自动 URL 检测器以显示实际的标题,而不是 http://...

<?php
echo get_url_title("https://php.net/cal.php?id=409");

function
get_url_title($url, $timeout = 2)
{
$url = parse_url($url);

if(!
in_array($url['scheme'],array('','http')))
return;

$fp = fsockopen ($url['host'], ($url['port'] > 0 ? $url['port'] : 80), $errno, $errstr, $timeout);
if (!
$fp)
{
return;
// echo "$errstr ($errno)<br>\n";
}
else
{
fputs ($fp, "GET /".$url['path'].($url['query'] ? '?'.$url['query'] : '')." HTTP/1.0\r\nHost: ".$url['host']."\r\n\r\n");
$d = '';
while (!
feof($fp))
{
$d .= fgets ($fp,2048);

if(
preg_match('~(</head>|<body>|(<title>\s*(.*?)\s*</title>))~i', $d, $m))
break;
}
fclose ($fp);

return
$m[3];
}
}
?>
2
huli0401 at gmail dot com
16 年前
<?php
// Check for new version
$current_version = explode('.', '1.0.00');
$minor_revision = (int) $current_version[2];

$errno = 0;
$errstr = $version_info = '';

if (
$fsock = fsockopen("www.exanmple.eu", 80, $errno, $errstr, 30))
{
@
fputs($fsock, "GET /ver.txt HTTP/1.1\r\n");
@
fputs($fsock, "HOST: www.example.eu\r\n");
@
fputs($fsock, "Connection: close\r\n\r\n");

$get_info = false;
while (!@
feof($fsock))
{
if (
$get_info)
{
$version_info .= @fread($fsock, 1024);
}
else
{
if (@
fgets($fsock, 1024) == "\r\n")
{
$get_info = true;
}
}
}
@
fclose($fsock);

$version_info = explode("\n", $version_info);
$latest_head_revision = (int) $version_info[0];
$latest_minor_revision = (int) $version_info[2];
$latest_version = (int) $version_info[0] . '.' . (int) $version_info[1] . '.' . (int) $version_info[2];

if (
$latest_head_revision == 2 && $minor_revision == $latest_minor_revision)
{
$version_info = '<p style="color:green">OK</p>';
}
else
{
$version_info = '<p style="color:red">neaktualne';
$version_info .= '<br />'Latest_version_info' . $latest_version) . ' ' . sprintf(Current_version_info'. '1.0.00') . '</p>';
}
}
else
{
if (
$errstr)
{
$version_info = '<p style="color:red">' . sprintf(Connect_socket_error) . '</p>';
}
else
{
$version_info = '<p>'Socket_functions_disabled'</p>';
}
}

$version_info .= '<p>'Mailing_list_subscribe_reminder'</p>';

echo
$version_info;
?>
4
verran at descent-rangers dot com
21 年前
我绞尽脑汁想弄清楚如何做到这一点,持续了一周时间。

如果你对没有 EOF 服务使用 fsockopen,或者尝试在 EOF 或换行符之后读取,PHP 会完全挂起。

在我的案例中,我尝试编写一个类与 Kali 服务器(www.kali.net)交互以获取聊天服务器上的人员列表。为了防止 PHP 由于上述原因而挂起,我发现了以下代码:

<?php
kali_utils {
功能
games_list($kali_server_ip, $kali_server_port) {
$结果 = 数组();
$fp = fsockopen($kali_server_ip, $kali_server_port, $errno, $error, 30);
如果 (!
$fp) {
$结果["错误号"] = $errno;
$结果["错误"] = $error;
}
否则 {
fputs($fp, "KALIQ");
$报头 = fread($fp, 5);
$剩余字节 = socket_get_status($fp);
如果 (
$剩余字节 > 0) {
$结果["结果"] = fread($fp, $剩余字节["未读字节"]);
}
否则 {
$结果["结果"] = "";
}
fclose($fp);
}
返回
$结果;
}
}
?>

当我发送请求数据包时,我得到一个长度为 5 的响应数据包。然后我调用 socket_get_status() 并使用其中的 unread_bytes 关键字来了解从套接字读取多远的数据。效果非常好。

到目前为止我只在 PHP 4.2.1 上使用过此方法。
5
[email protected]
15 年前
备注
如果没有提供默认协议,则默认似乎为 tcp://
4
[email protected]
19 年前
<?php
/************************************************************
* Author: Richard Lajaunie
* Mail : [email protected]
*
* subject : this script retreive all mac-addresses on all ports
* of a Cisco 3548 Switch by a telnet connection
*
* base on the script by: xbensemhoun at t-systems dot fr
**************************************************************/

if ( array_key_exists(1, $argv) ){
$cfgServer = $argv[1];
}else{
echo
"ex: 'php test.php 10.0.0.0' \n";
exit;
}

$cfgPort = 23; //port, 22 if SSH
$cfgTimeOut = 10;

$usenet = fsockopen($cfgServer, $cfgPort, $errno, $errstr), $cfgTimeOut);

if(!
$usenet){
echo
"Connexion failed\n";
exit();
}else{
echo
"Connected\n";
fputs ($usenet, "password\r\n");
fputs ($usenet, "en\r\n");
fputs ($usenet, "password\r\n");
fputs ($usenet, "sh mac-address-table\r\n");
fputs ($usenet, " "); // this space bar is this for long output

// this skip non essential text
$j = 0;
while (
$j<16){
fgets($usenet, 128);
$j++;
}
stream_set_timeout($usenet, 2); // set the timeout for the fgets
$j = 0;
while (!
feof($usenet)){
$ret = fgets($usenet, 128);
$ret = str_replace("\r", '', $ret);
$ret = str_replace("\n", "", $ret);
if (
ereg("FastEthernet", $ret)){
echo
"$ret \n";
}
if (
ereg('--More--', $ret) ){
fputs ($usenet, " "); // for following page
}
$info = stream_get_meta_data($usenet);
if (
$info['timed_out']) {
$j++;
}
if (
$j >2){
fputs ($usenet, "lo");
break;
}
}
}
echo
"End.\r\n";
?>
5
Kiki_EF
18 年前
通过代理发出额外的 ICQ 状态请求
<?php
function icq_uin($uin)
{
if (!
is_numeric($uin))
return
false;
$proxy_name = 'proxy.mydomain.de';
$proxy_port = 8080;
$proxy_user = "";
$proxy_pass = "";
$proxy_cont = '';
$request_url = "http://status.icq.com/online.gif?icq=$uin";

$proxy_fp = fsockopen($proxy_name, $proxy_port);
if (!
$proxy_fp)
return
false;
fputs($proxy_fp, "GET $request_url HTTP/1.0\r\nHost: $proxy_name\r\n");
fputs($proxy_fp, "Proxy-Authorization: Basic ". base64_encode ("$proxy_user:$proxy_pass")."\r\n\r\n");
while(!
feof($proxy_fp)){
$proxy_cont .= fread($proxy_fp,4096);
}
fclose($proxy_fp);
$proxy_cont = substr($proxy_cont, strpos($proxy_cont,"\r\n\r\n")+4);
if (
strstr($proxy_cont, 'online1'))
return
'online';
if (
strstr($proxy_cont, 'online0'))
return
'offline';
if (
strstr($proxy_cont, 'online2'))
return
'disabled';
}
echo
"User is ".icq_uin(123456789012345);
?>

谢谢

[danbrown 在 php DOT net 编辑:基于 (rafaelbc AT matrix DOT com DOT br) 于 23-MAY-09 所提供的一则笔记中的代码,该代码已被删除。]
6
robin at pozytron dot com
18 年前
我发现,当使用 fsockopen() 和 POST 方法时,使用 HTTP/1.1 的速度显著慢于 HTTP/1.0(至少对于我所查询的基于 Orion 的服务器),而且使用 cURL 往往比 fsockopen() 的速度更快,但快得不多。例如,这里有一组最近的数据(针对每个情况下的完全相同请求)

cURL:4.2 秒
fsockopen() HTTP/1.0:4.9 秒
fsockopen() HTTP/1.1:19.9 秒(!

我不确定为什么会发生这种情况。也许这与 Orion 服务器有关,我对它了解不多。然而,这并非偶然,我仔细检查了代码以确保没有错误。

编辑器注释:HTTP/1.1 使用持久连接导致此延迟。使用“Connection: close”标头来禁用它。
3
edwin at bitstorm dot org
19 年前
这是一个仅获取 URL 背后内容的函数。

<?php
函数fetchURL$url){
$url_parsed = parse_url($url);
$host = $url_parsed["host"];
$port = $url_parsed["port"];
如果(
$port==0
$port = 80;
$path = $url_parsed["path"];
如果(
$url_parsed["query"] != ""
$path .= "?".$url_parsed["query"];

$out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";

$fp = fsockopen($host, $port, $errno, $errstr, 30);

fwrite($fp, $out);
$body = false;
while (!
feof($fp)) {
$s = fgets($fp, 1024);
如果(
$body
$in .= $s;
如果(
$s == "\r\n"
$body = true;
}

fclose($fp);

返回
$in;
}
?>
5
brage (a t) jeffnappi (d.o.t) commie
21 年前
认为你们可能会欣赏这个函数,它允许您传递要下载的 URL 数组,并使用非阻塞套接字同时执行此操作,然后将数据返回为一个数组。

<?php
// function connects to an array of URLS at the same time
// and returns an array of results.

function multiHTTP ($urlArr) {
$sockets = Array(); // socket array!
$urlInfo = Array(); // info arr
$retDone = Array();
$retData = Array();
$errno = Array();
$errstr = Array();
for (
$x=0;$x<count($urlArr);$x++) {
$urlInfo[$x] = parse_url($urlArr[$x]);
$urlInfo[$x][port] = ($urlInfo[$x][port]) ? $urlInfo[$x][port] : 80;
$urlInfo[$x][path] = ($urlInfo[$x][path]) ? $urlInfo[$x][path] : "/";
$sockets[$x] = fsockopen($urlInfo[$x][host], $urlInfo[$x][port],
$errno[$x], $errstr[$x], 30);
socket_set_blocking($sockets[$x],FALSE);
$query = ($urlInfo[$x][query]) ? "?" . $urlInfo[$x][query] : "";
fputs($sockets[$x],"GET " . $urlInfo[$x][path] . "$query HTTP/1.0\r\nHost: " .
$urlInfo[$x][host] . "\r\n\r\n");
}
// ok read the data from each one
$done = false;
while (!
$done) {
for (
$x=0; $x < count($urlArr);$x++) {
if (!
feof($sockets[$x])) {
if (
$retData[$x]) {
$retData[$x] .= fgets($sockets[$x],128);
} else {
$retData[$x] = fgets($sockets[$x],128);
}
} else {
$retDone[$x] = 1;
}
}
$done = (array_sum($retDone) == count($urlArr));
}
return
$retData;
}
?>
6
Alexander Wegener
17 年前
检查 URL 是否联机(使用 http 和 https)
使用 @fgets 在使用 SSL 时隐藏警告
(缺陷:“警告:function.fgets SSL:致命协议错误”,http://bugs.php.net/bug.php?id=23220)

<?php

function isOnline($url) {
if (!
$url_info = parse_url($url)) {
return
false;
}

switch (
$url_info['scheme']) {
case
'https':
$scheme = 'ssl://';
$port = 443;
break;
case
'http':
default:
$scheme = '';
$port = 80;
}

$data = "";
$fid = @fsockopen($scheme . $url_info['host'], $port, $errno, $errstr, 30);
if (
$fid) {
fputs($fid, 'HEAD ' . (isset($url_info['path'])? $url_info['path']: '/') . (isset($url_info['query'])? '?' . $url_info['query']: '') . " HTTP/1.0\r\n" .
"Connection: close\r\n" .
'Host: ' . $url_info['host'] . "\r\n\r\n");
while (!
feof($fid)) {
$data .= @fgets($fid, 128);
}
fclose($fid);
return !empty(
$data);
} else {
return
false;
}
}

?>
1
GreenReaper
5 年前
PHP(或 OpenSSL)可能并不总是选择使用 TLS 1.2,但您可以强制使用 tlsv1.2://
https://docs.php.net/manual/en/migration56.openssl.php#migration56.openssl.crypto-method

这对我来说帮助极大,因为 Twitter 最近的 API 更改要求使用 TLS 1.2+。
6
nytro_rst at yahoo dot com
14 年前
一个简单的代理列表检查器。如果 IP 上开启了该端口,您可以检查 ip:port 列表。

<?php

$fisier
= file_get_contents('proxy_list.txt'); // 获取代理列表所在的文本文件
$linii = explode("\n", $fisier); // 获取每个代理
$fisier = fopen("bune.txt", "a"); // 在此文本文件中将这些代理写出

for($i = 0; $i < count($linii) - 1; $i++) test($linii[$i]); // 测试每个代理

function test($proxy)
{
global
$fisier;
$splited = explode(':',$proxy); // 分离 IP 和端口
if($con = @fsockopen($splited[0], $splited[1], $eroare, $eroare_str, 3))
{
fwrite($fisier, $proxy . "\n"); // 检查是否可以连接到该 IP 和端口
print $proxy . '<br>'; // 显示代理
fclose($con); // 关闭套接字句柄
}
}

fclose($fisier); // 关闭该文本文件

?>
3
saul dot dobney at dobney dot com
19 年前
如果您使用 fsockopen 来访问网页,但在标题中遇到重定向 (Location: ),并且想要像在此片段中那样,找到并遵循重定向

<?php
while (!feof($fp)) {
$line=fgets($fp, 1024);
if (
stristr($line,"location:")!="") {
$redirect=preg_replace("/location:/i","",$line);
}
}
?>

然后不要忘记 <?php $redirect = trim($redirect); ?> 在尝试访问该新链接之前进行修剪,因为 $redirect 实际上末尾有一个 \r\n,否则它不会为下一次迭代提供一个有效的路径。一个六小时的错误。

Saul Dobney
1
bradland at umich dot edu
17 年前
我在使用 fopen 和 fsockopen 时遇到用 https 访问地址 ssl:// 时出现问题。我在日志中收到 114 错误代码。经过大量研究,我发现 MySQL 5.0.20-5.0.33 存在一些 ssl 冲突问题。它有一些函数与 openssl 冲突,并且出现在 PHP 安装中。

http://bugs.mysql.com/bug.php?id=21930
http://bugs.mysql.com/bug.php?id=19289
1
v13+phpnet at it dot teithe dot gr
17 年前
以下函数执行 pop3 认证。出现错误时返回 NULL,或返回 true/false 以指示用户名/密码匹配

$address 是服务器的主机名,$ssl 是一个指示是否请求 SSL 连接的布尔值。

<?php
function pop3authCheck($username, $password, $address, $ssl)
{
if (
$ssl)
$uri="ssl://$address:995";
else
$uri="tcp://$address:110";

$fp=fsockopen($uri);

if (!
$fp)
return(
NULL);

$st=fgets($fp, 512);
if (
substr($st, 0, 3)!="+OK")
{
fclose($fp);
return(
NULL);
}

$st="USER $username\n";
if (
fwrite($fp, $st)!=strlen($st))
{
fclose($fp);
return(
NULL);
}

$st=fgets($fp, 512);
if (
substr($st, 0, 3)!="+OK")
{
fclose($fp);
return(
NULL);
}

$st="PASS $password\n";
if (
fwrite($fp, $st)!=strlen($st))
{
fclose($fp);
return(
NULL);
}

$st=fgets($fp, 512);
fclose($fp);
if (
substr($st, 0, 3)=="+OK")
return(
true);
else if (
substr($st, 0, 4)=="+ERR")
return(
false);
else
return(
NULL);
}
?>
1
Duukkis
18 年前
大量尝试和大量阅读 http 头信息...

如果您想将 $_POST 变量和(在本例中)一个名为 userfile 的文件发送到 $remote_server 和 $remote_url。

<?php
// get the necessary data
$file_name = $_FILES['userfile']['name']; // the file
$tmp_name = $_FILES['userfile']['tmp_name']; // the file
$content_type = $_FILES['userfile']['type']; // the file mime type

srand((double)microtime()*1000000);
$boundary = "---------------------".substr(md5(rand(0,32000)),0,10);

// Build the header
$header = "POST $remote_url HTTP/1.0\r\n";
$header .= "Host: $remote_server\r\n";
$header .= "Content-type: multipart/form-data, boundary=$boundary\r\n";
// attach post vars
foreach($_POST AS $index => $value){
$data .="--$boundary\r\n";
$data .= "Content-Disposition: form-data; name=\"".$index."\"\r\n";
$data .= "\r\n".$value."\r\n";
$data .="--$boundary\r\n";
}
// and attach the file
$data .= "--$boundary\r\n";
$content_file = join("", file($tmp_name));
$data .="Content-Disposition: form-data; name=\"userfile\"; filename=\"$file_name\"\r\n";
$data .= "Content-Type: $content_type\r\n\r\n";
$data .= "".$content_file."\r\n";
$data .="--$boundary--\r\n";
$header .= "Content-length: " . strlen($data) . "\r\n\r\n";
// Open the connection
$fp = fsockopen($remote_server, 80);
// then just
fputs($fp, $header.$data);
fclose($fp);
?>
1
blazely at removetoemail netspace net au
21 年前
这是一个快速函数,用于建立与 Web 服务器的连接,如果连接在用户可定义的时间间隔后丢失或无法访问服务器,则连接将超时。

如果指定了用户名/密码,还支持基本认证。如有任何改进或批评,请给我发送电子邮件! :-)

返回资源 ID、错误代码,或者在根本无法访问服务器时返回 0。万一发生某些真正奇怪的情形(如非标准的 http 响应),则返回 -1。希望对某人有帮助。

此致敬礼,

Ben Blazely

<?php
function connectToURL($addr, $port, $path, $user="", $pass="", $timeout="30")
{
$urlHandle = fsockopen($addr, $port, $errno, $errstr, $timeout);
if (
$urlHandle)
{
socket_set_timeout($urlHandle, $timeout);
if (
$path)
{
$urlString = "GET $path HTTP/1.0\r\nHost: $addr\r\nConnection: Keep-Alive\r\nUser-Agent: MyURLGrabber\r\n";
if (
$user)
$urlString .= "Authorization: Basic ".base64_encode("$user:$pass")."\r\n";
$urlString .= "\r\n";

fputs($urlHandle, $urlString);

$response = fgets($urlHandle);

if (
substr_count($response, "200 OK") > 0) // Check the status of the link
{
$endHeader = false; // Strip initial header information
while ( !$endHeader)
{
if (
fgets($urlHandle) == "\r\n")
$endHeader = true;
}

return
$urlHandle; // All OK, return the file handle
}
else if (
strlen($response) < 15) // Cope with wierd non standard responses
{
fclose($urlHandle);
return -
1;
}
else
// Cope with a standard error response
{
fclose($urlHandle);
return
substr($response,9,3);
}
}

return
$urlHandle;
}
else
{
return
0;
}
}
}
?>
1
dan at lovepond dot com
21 年前
这里有一些代码,可以帮助我们更多地解决 EOF 问题。
我曾遇到过一个问题,我需要掐掉很多行服务器输入才能获得我想要的数据。

<?php
$port
=4000;
$host="localhost";
$message="test";
$status=senddata($host,$port,$message);
print
"$status";

function
senddata($host,$port,$message) {

#takes in account servers that do not return EOF character
#send data to server and get back input

#function globals
$linenumber="2"; #amount of lines to get rid of before we give input
$lineamount="1"; #amount of lines to read after we give input

$fp = fsockopen("$host", $port, $errno, $errstr, 30);
if (!
$fp) {
echo
"$errstr ($errno)";
}
else {
for (
$i = 1; $i < $linenumber+1; $i++) {
fread ($fp,1);
$bytes_left = socket_get_status($fp);
if (
$bytes_left > 0) { fread($fp, $bytes_left[unread_bytes]); }
}
fputs($fp, "$message\r\n");
for (
$i = 1; $i < $lineamount+1; $i++) {
$status.=fread($fp,1);
$bytes_left = socket_get_status($fp);
if (
$bytes_left > 0) { $status.=fread($fp, $bytes_left[unread_bytes]); }
}
fclose ($fp);
}

return
$status;
}

?>
1
oliver dot christen at camptocamp dot com
15 年前
下载大文件时,在解析数据以删除标头部分之前将整个服务器答案放入内存中并不是很有效。这里提供了一种简单的方法,可以在数据来临时将其写入

<?php

// $socket 是一个有效的 fsockopen 句柄

$out = '';
$headerendfound = false;
$fp = fopen($fileTarget, 'w');
$buffer = '';
while (!
feof($socket)) {
$out = fgets ($socket,16384);
if (
$headerendfound) {
fwrite($fp, $out);
print
'.';
}
if (!
$headerendfound) {
$buffer .= $out;
print
"searching for header\n";
$headerend = strpos($buffer, "\r\n\r\n");
if (
$headerend !== false) {
$headerendfound = true;
fwrite($fp, substr($buffer, $headerend+4));
$buffer = '';
}
}
}
fclose($fp);
fclose($socket);

?>
1
konrad dot meyer at gmail dot com
19 年前
该文档示例是一个 GET 请求。我发现缺少 POST 文档,下面是一个轻松模拟提交表单数据的函数

<?php
# $host 包括主机和路径和文件名
# 例如: "myserver.com/this/is/path/to/file.php"
# $query 是 POST 查询数据
# 例如: "a=thisstring&number=46&string=thatstring
# $others 是你要发送的任何额外标头
# 例如: "Accept-Encoding: compress, gzip\r\n"
function post($host,$query,$others=''){
$path=explode('/',$host);
$host=$path[0];
unset(
$path[0]);
$path='/'.(implode('/',$path));
$post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-www-form-urlencoded\r\n${others}User-Agent: Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
$h=fsockopen($host,80);
fwrite($h,$post);
for(
$a=0,$r='';!$a;){
$b=fread($h,8192);
$r.=$b;
$a=(($b=='')?1:0);
}
fclose($h);
return
$r;
}
?>
3
asalamanca at redcetus.com
20 年前
这是一个极快程序,可用于测试一个表单或链接(多次)。
<?php
$repeat
= 100; // How many times repeat the test

$timeout = 100; // Max time for stablish the conection
$size = 16; // Bytes will be read (and display). 0 for read all

$server = '127.0.0.1'; // IP address
$host = 'www.example.net'; // Domain name
$target = '/poll/answer.asp'; // Specific program
$referer = 'http://www.example.com/'; // Referer
$port = 80;

// Setup an array of fields to get with then create the get string
$gets = array ( 'get_field_1' => 'somevalue',
'get_field_2' => 'somevalue' );

// Setup an array of fields to post with then create the post string
$posts = array ( 'post_field_1' => 'somevalue',
'post_field_2' => 'somevalue' );

// That's all. Now the program proccess $repeat times

$method = "GET";
if (
is_array( $gets ) ) {
$getValues = '?';
foreach(
$gets AS $name => $value ){
$getValues .= urlencode( $name ) . "=" . urlencode( $value ) . '&';
}
$getValues = substr( $getValues, 0, -1 );
} else {
$getValues = '';
}

if (
is_array( $posts ) ) {
foreach(
$posts AS $name => $value ){
$postValues .= urlencode( $name ) . "=" . urlencode( $value ) . '&';
}
$postValues = substr( $postValues, 0, -1 );
$method = "POST";
} else {
$postValues = '';
}

$request = "$method $target$getValues HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request .= 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) ';
$request .= "Gecko/20021204\r\n";
$request .= 'Accept: text/xml,application/xml,application/xhtml+xml,';
$request .= 'text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,';
$request .= "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n";
$request .= "Accept-Language: en-us, en;q=0.50\r\n";
$request .= "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n";
$request .= "Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66\r\n";
$request .= "Keep-Alive: 300\r\n";
$request .= "Connection: keep-alive\r\n";
$request .= "Referer: $referer\r\n";
$request .= "Cache-Control: max-age=0\r\n";

if (
$method == "POST" ) {
$lenght = strlen( $postValues );
$request .= "Content-Type: application/x-www-form-urlencoded\r\n";
$request .= "Content-Length: $lenght\r\n";
$request .= "\r\n";
$request .= $postValues;
}

for (
$i = 0; $i < $repeat; $i++ ) {
$socket = fsockopen( $server, $port, $errno, $errstr, $timeout );
fputs( $socket, $request );
if (
$size > 0 ) {
$ret = fgets( $socket, $size );
} else {
$ret = '';
while ( !
feof( $socket ) ) {
$ret .= fgets( $socket, 4096 );
}
}
fclose( $socket );
echo
"<hr> $i -- $content $ret";
}
?>

Alejandro Salamanca
2
无政府状态
16 年前
根据 php.ini 文件中的 default_socket_timeout 设置默认流超时。花了我很长时间才弄明白这一点...
2
Jeremy Saintot
13 年前
以下是基于 fsockopen 的 HTTP 请求函数(GET 和 POST)

<?php
function http_request(
$verb = 'GET', /* HTTP Request Method (GET and POST supported) */
$ip, /* Target IP/Hostname */
$port = 80, /* Target TCP port */
$uri = '/', /* Target URI */
$getdata = array(), /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$postdata = array(), /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$cookie = array(), /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
$timeout = 1, /* Socket timeout in seconds */
$req_hdr = false, /* Include HTTP request headers */
$res_hdr = false /* Include HTTP response headers */
)
{
$ret = '';
$verb = strtoupper($verb);
$cookie_str = '';
$getdata_str = count($getdata) ? '?' : '';
$postdata_str = '';

foreach (
$getdata as $k => $v)
$getdata_str .= urlencode($k) .'='. urlencode($v) . '&';

foreach (
$postdata as $k => $v)
$postdata_str .= urlencode($k) .'='. urlencode($v) .'&';

foreach (
$cookie as $k => $v)
$cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';

$crlf = "\r\n";
$req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
$req .= 'Host: '. $ip . $crlf;
$req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
$req .= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . $crlf;
$req .= 'Accept-Language: en-us,en;q=0.5' . $crlf;
$req .= 'Accept-Encoding: deflate' . $crlf;
$req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf;

foreach (
$custom_headers as $k => $v)
$req .= $k .': '. $v . $crlf;

if (!empty(
$cookie_str))
$req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf;

if (
$verb == 'POST' && !empty($postdata_str))
{
$postdata_str = substr($postdata_str, 0, -1);
$req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
$req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
$req .= $postdata_str;
}
else
$req .= $crlf;

if (
$req_hdr)
$ret .= $req;

if ((
$fp = @fsockopen($ip, $port, $errno, $errstr)) == false)
return
"Error $errno: $errstr\n";

stream_set_timeout($fp, 0, $timeout * 1000);

fputs($fp, $req);
while (
$line = fgets($fp)) $ret .= $line;
fclose($fp);

if (!
$res_hdr)
$ret = substr($ret, strpos($ret, "\r\n\r\n") + 4);

return
$ret;
}
?>

用法示例

<?php
echo http_request('GET', 'www.php.net');
echo
http_request('GET', 'www.php.net', 80, '/manual/en/function.phpinfo.php');
echo
http_request('GET', 'www.php.net', 80, '/manual/en/function.phpinfo.php', array('get1' => 'v_get1'), array(), array('cookie1' => 'v_cookie1'), array('X-My-Header' => 'My Value'));
?>

[EDIT BY danbrown AT php DOT net: 包含由“Wrinkled Cheese”提供的漏洞修复,时间在 24-JUN-2011,用于修复 $getdata foreach() 循环;另一漏洞修复由 Suat Secmen 提供,时间在 12-JAN-2012,用于修复 $timeout = 1000,然后 stream_set_timeout($fp, 0, $timeout * 1000),等于 1000 秒。]
1
richardaburton at hotmail dot com
20 年前
改进了 HTTP/1.1 分块传输编码示例。

Jack 在下面给出的示例代码在针对较新版本的 Apache 运行时无法正常运行(我假设这是曾经有效的一次,但从 HTTP/1.1 规范来看,我只能假设如果它确实起作用,它主要是基于运气)。

<?php

$header
= "";
$response = "";

// connect
if (!($request=fsockopen('example.com',80,$errno,$errstr))) exit($errstr);
else {
socket_set_timeout($request,10);
// send request
fwrite($request,$post);
// get header
do $header.=fread($request,1); while (!preg_match('/\\r\\n\\r\\n$/',$header));
// check for chunked encoding
if (preg_match('/Transfer\\-Encoding:\\s+chunked\\r\\n/',$header))
do {
$byte = "";
$chunk_size="";
do {
$chunk_size.=$byte;
$byte=fread($request,1);
} while (
$byte!="\\r"); // till we match the CR
fread($request, 1); // also drop off the LF
$chunk_size=hexdec($chunk_size); // convert to real number
$response.=fread($request,$chunk_size);
fread($request,2); // ditch the CRLF that trails the chunk
} while ($chunk_size); // till we reach the 0 length chunk (end marker)
else {
// check for specified content length
if (preg_match('/Content\\-Length:\\s+([0-9]*)\\r\\n/',$header,$matches)) {
$response=fread($request,$matches[1]);
} else {
// not a nice way to do it (may also result in extra CRLF which trails the real content???)
while (!feof($request)) $response .= fread($request, 4096);
}
}
// close connection
fclose($request);
}

// do something useful with the response
print($header);
print(
$response);

?>

Richard。
1
iain at monitormedia dot co dot uk
22 年前
以下是如何使用 SMTP 发送电子邮件。这包括在发送电子邮件过程中对服务器响应进行基本的检查。可以通过对结果代码进行更加全面的处理...或在连接到第一个邮件交换服务器后连接失败时,转到下一个邮件交换服务器来改进。

<?php

function another_mail($to,$subject,$headers,$message)
{
// Could get this from the php ini?
$from="[email protected]";
list(
$me,$mydomain) = split("@",$from);

// Now look up the mail exchangers for the recipient
list($user,$domain) = split("@",$to,2);
if(
getmxrr($domain,$mx,$weight) == 0) return FALSE;

// Try them in order of lowest weight first
array_multisort($mx,$weight);
$success=0;

foreach(
$mx as $host) {
// Open an SMTP connection
$connection = fsockopen ($host, 25, $errno, $errstr, 1);
if (!
$connection)
continue;
$res=fgets($connection,256);
if(
substr($res,0,3) != "220") break;

// Introduce ourselves
fputs($connection, "HELO $mydomain\n");
$res=fgets($connection,256);
if(
substr($res,0,3) != "250") break;

// Envelope from
fputs($connection, "MAIL FROM: $from\n");
$res=fgets($connection,256);
if(
substr($res,0,3) != "250") break;

// Envelope to
fputs($connection, "RCPT TO: $to\n");
$res=fgets($connection,256);
if(
substr($res,0,3) != "250") break;

// The message
fputs($connection, "DATA\n");
$res=fgets($connection,256);
if(
substr($res,0,3) != "354") break;

// Send To:, From:, Subject:, other headers, blank line, message, and finish
// with a period on its own line.
fputs($connection, "To: $to\nFrom: $from\nSubject: $subject\n$headers\n\n$message\n.\n");
$res=fgets($connection,256);
if(
substr($res,0,3) != "250") break;

// Say bye bye
fputs($connection,"QUIT\n");
$res=fgets($connection,256);
if(
substr($res,0,3) != "221") break;

// It worked! So break out of the loop which tries all the mail exchangers.
$success=1;
break;
}
// Debug for if we fall over - uncomment as desired
// print $success?"Mail sent":"Failure: $res\n";
if($connection) {
if(
$success==0) fputs($connection, "QUIT\n");
fclose ($connection);
}
return
$success?TRUE:FALSE;
}

another_mail("[email protected]","My Subject","X-mailer: PHP Script\nX-another-header: Whatever","Test email body.\n\nNote if you actually put a period on a line\nby itself, the function will terminate prematurely.\n\nYou will get a partial email sent though.\n");
?>
1
xbensemhoun at t-systems dot fr
21 年前
使用 Cisco 路由器建立 telnet 连接

<?php
$cfgServer
= "nnn.nnn.nnn.nnn"; // 路由器的 IP
$cfgPort = 23; // 端口,如果是 SSH 则为 22
$cfgTimeOut = 10;

$usenet = fsockopen($cfgServer, $cfgPort, $errno, $errstr, $cfgTimeOut);

if(!
$usenet)
{
echo
"Connexion failed\n";
exit();
}
else
{
echo
"已连接\n<BR>";
fputs ($usenet, "toto\r\n");
fputs ($usenet, "en\r\n");
fputs ($usenet, "tutu\r\n");
fputs ($usenet, "exit\r\n");
while (!
feof($usenet))
{
echo
". ".fgets($usenet, 128)."<BR>\n";
}
}
?>

然后你会看到
已连接
. �� �� �� ��
.
. 用户访问验证
.
. 密码
. testXB>en
. 密码
. testXB#exit
.
1
Goce Dokoski
5 年前
试图 fsockopen 一个 ssl:// 连接,但挂起时间很长,忽略超时参数,最终返回 false,没有错误消息。

结果证明(至少在 Windows 上)它验证了证书并且没有有效的证书存储。

以下是对我有效的方法

- 从 https://curl.haxx.se/ca/cacert.pem 下载 Mozilla 的证书存储
- 将其复制到 php 安装中(例如:c:\php)
- 并在 php.ini 中设置它

openssl.cafile="c:\php\cacert.pem"

我的系统:Apache/2.4.29 (Win64) OpenSSL/1.0.2n PHP/5.6.38
1
p14nd4
10 年前
PHP 5.6.0(至少是 openssl 1.0.1h-3 的 Debian jessie 中的版本)中似乎验证 SSL 证书(有多种方式)。首先,它似乎会因不受信任的证书(即没有匹配的本地受信任 CA)失败,其次,它似乎会因请求和证书中的主机名不匹配而失败。

---------
$ echo "<?php echo fsockopen(\"ssl://localhost\", 993); ?>" | php -a
启用了交互模式

PHP 警告
: fsockopen(): 对等证书 CN=`my.test.server' 未与预期的 CN=`localhost' 匹配 - 在第 1 行
PHP 警告: fsockopen(): 无法在 - 的第 1 行启用加密
PHP 警告: fsockopen(): 无法连接到 ssl://localhost:993(未知错误) - 在第 1 行
----------
$ echo "<?php echo fsockopen(\"ssl://my.test.server\", 993); ?>" | php -a
启用了交互模式

PHP 警告: fsockopen(): SSL 操作失败,代码为 1。OpenSSL 错误消息:
error:14090086:SSL 程序:SSL3_GET_SERVER_CERTIFICATE:证书验证失败 - 在第 1 行
PHP 警告: fsockopen(): 无法在 - 的第 1 行启用加密
PHP 警告: fsockopen(): 无法连接到 ssl://my.test.server:993(未知错误) - 在第 1 行
---------
# 在本地安装 CA
---------
$ echo "<?php echo fsockopen(\"ssl://my.test.server\", 993); ?>" | php -a
启用了交互模式

资源标识符 #1
0
jszoja at gmail dot com
1 年前
如果使用 @ 等方式禁止错误,则通过 `unix//` 协议打开不存在的套接字文件也会导致异常
<?php
$fh
= @fsockopen('unix:///var/run/file-not-exists.sock');
?>

从 PHP 7.4 迁移到 8.x 时了解这一点很重要,因为用 @ 禁止错误的方式已经更改。
0
kexianbin at diyism dot com
12 年前
我的递归解块函数

<?php
function unchunk($result)
{return
preg_replace('/([0-9A-F]+)\r\n(.*)/sie',
'($cnt=@base_convert("\1", 16, 10))
?substr(($str=@strtr(\'\2\', array(\'\"\'=>\'"\', \'\\\\0\'=>"\x00"))), 0, $cnt).unchunk(substr($str, $cnt+2))
:""
'
,
$result
);
}
?>
0
jabeba at web dot de
16 年前
如果你必须使用代理在本地网络之外进行请求,你可以使用这个类

<?php
/*
*
* No Proxy Authentification Implemented; PHP 5
*
*/

class RemoteFopenViaProxy {

private
$result;
private
$proxy_name;
private
$proxy_port;
private
$request_url;

public function
get_proxy_name() {
return
$this->proxy_name;
}

public function
set_proxy_name($n) {
$this->proxy_name = $n;
}

public function
get_proxy_port() {
return
$this->proxy_port;
}

public function
set_proxy_port($p) {
$this->proxy_port = $p;
}

public function
get_request_url() {
return
$this->request_url;
}

public function
set_request_url($u) {
$this->request_url = $u;
}

public function
get_result() {
return
$this->result;
}

public function
set_result($r) {
$this->result = $r;
}

private function
get_url_via_proxy() {

$proxy_fp = fsockopen($this->get_proxy_name(), $this->get_proxy_port());

if (!
$proxy_fp) {
return
false;
}
fputs($proxy_fp, "GET " . $this->get_request_url() . " HTTP/1.0\r\nHost: " . $this->get_proxy_name() . "\r\n\r\n");
while (!
feof($proxy_fp)) {
$proxy_cont .= fread($proxy_fp, 4096);
}
fclose($proxy_fp);
$proxy_cont = substr($proxy_cont, strpos($proxy_cont, "\r\n\r\n") + 4);
return
$proxy_cont;

}

private function
get_url($url) {
$fd = @ file($url);
if (
$fd) {
return
$fd;
} else {
return
false;
}
}

private function
logger($line, $file) {
$fd = fopen($file . ".log", "a+");
fwrite($fd, date("Ymd G:i:s") . " - " . $file . " - " . $line . "\n");
fclose($fd);
}

function
__construct($url, $proxy_name = "", $proxy_port = "") {

$this->set_request_url($url);
$this->set_proxy_name($proxy_name);
$this->set_proxy_port($proxy_port);

}

public function
request_via_proxy() {

$this->set_result($this->get_url_via_proxy());
if (!
$this->get_result()) {
$this->logger("FAILED: get_url_via_proxy(" . $this->get_proxy_name() . "," . $this->get_proxy_port() . "," . $this->get_request_url() . ")", "RemoteFopenViaProxyClass.log");
}
}

public function
request_without_proxy() {

$this->set_result($this->get_url($this->get_request_url()));
if (!
$this->get_result()) {
$this->logger("FAILED: get_url(" . $url . ")", "RemoteFopenViaProxyClass.log");
}
}
}
?>

按如下方式使用

<?php
// 调用构造函数
$obj = new RemoteFopenViaProxy($insert_request_url, $insert_proxy_name, $insert_proxy_port);
// 生成对象后更改设置
$obj->set_proxy_name($insert_proxy_name);
$obj->set_proxy_port($insert_proxy_port);
$obj->set_request_url($insert_request_url);
$obj->request_via_proxy();
echo
$obj->get_result();
?>

如果在执行期间出错,脚本会尝试将一些有用信息写入日志文件。
-1
walter
15 年前
出于某种原因,默认的 FreeBSD 7.0 端口(受限环境)中,在 SSL URL 上的 fsockopen() 已损坏,不断返回空流!在我的案例中,这导致 php-cgi 在短时间内完全终止了 lighttpd!避免 FreeBSD/受限/fsockopen + SSL。最好使用 curl_init()。
-1
gratcypalma at gmail dot com
13 年前
<?php
/*
this script i used for remote my PvPGN Server, to check email user.
not good, but it work.
*/

set_time_limit(0);
$host = 'host';
$port = 'port';
$user = 'user';
$pass = 'pass';
$socket = fsockopen($host, $port) or die('Could not connect to: '.$host);
$userdota = "palma";
if(
$socket)
{
sendcmd("\r",$socket);
$status = "open"; // set status open

while($status=="open") //while we are connected to the server
{
$line = @fgets($socket, 1024) ;
/////////////login////////////////
if (strstr($line, "there is no guest account"))
{
sendcmd($user."\r\n",$socket);
sendcmd($pass."\r\n",$socket);
}
//////////////send command ////////////////////
if (strstr($line,"Your unique name: ".$user))
{
sendcmd("/finger ".$userdota."\r\n",$socket);
}

//////////////get email////////////////////
if (strstr($line,"email:")) // if respone server write "email:"
{
$pattern = '/email:(.*) ,/';
preg_match($pattern, $line, $matches);
fclose($socket);
$status="close"; // status close
$matches=str_replace(" ","", $matches);
$matches=str_replace(",is_operator:0,is_admin:0,","", $matches);
$matches=str_replace("email:","", $matches);
print
$matches[0];
$email=$matches[0];
}
if (
strstr($line,"ERROR: Invalid user.")) // if respone server write "ERROR: Invalid user."
{

fclose($socket);
$status="close";
$error ="Invalid User"; // error message
}

////////////login failed //////////////////////////
if (strstr($line, "Login failed")) // if respone server write "Login failed"
{
$error = "Login Failed"; // error message
fclose($socket);
$status="close";
}

flush(); // close

}

}
function
sendcmd($cmd,$socket) // send command function
{
fputs($socket, $cmd, strlen($cmd));
}
?>
-1
jack at jtr dot de
20 年前
这是一个用于测试网站/URI 可用性的函数

<?php
/*
* @return boolean
* @param string $link
* @desc ?berpr?ft die angegeben URL auf Erreichbarkeit (HTTP-Code: 200)
*/
function url_validate( $link )
{
$url_parts = @parse_url( $link );

if ( empty(
$url_parts["host"] ) ) return( false );

if ( !empty(
$url_parts["path"] ) )
{
$documentpath = $url_parts["path"];
}
else
{
$documentpath = "/";
}

if ( !empty(
$url_parts["query"] ) )
{
$documentpath .= "?" . $url_parts["query"];
}

$host = $url_parts["host"];
$port = $url_parts["port"];
// Now (HTTP-)GET $documentpath at $host";

if (empty( $port ) ) $port = "80";
$socket = @fsockopen( $host, $port, $errno, $errstr, 30 );
if (!
$socket)
{
return(
false);
}
else
{
fwrite ($socket, "HEAD ".$documentpath." HTTP/1.0\r\nHost: $host\r\n\r\n");
$http_response = fgets( $socket, 22 );

if (
ereg("200 OK", $http_response, $regs ) )
{
return(
true);
fclose( $socket );
} else
{
// echo "HTTP-Response: $http_response<br>";
return(false);
}
}
}
?>
-1
perrya at shoalhaven dot nsw dot gov dot au
8 年前
在我使用 Joomla 的 FreeBSD VM 上,我收到了错误

fsockopen():无法连接到 ssl://localhost:443 (未知错误)

在使用联系表单以及模块更新进程时出现错误。

在阅读了此处有关证书验证的其他注释后,我安装了端口 ca_root_nss

(包含在 Mozilla NSS 库中证书颁发机构的根证书
因此在 Firefox 和 Thunderbird 中)。

现在可以用了
-1
terminal
20 年前
请尝试以下操作。
必要时使用 AUTH。
遇到问题时阅读 RFC 821。

<?php

$handle
= smtp_connect($smtp_server, 25, 30, 1, 1, 1);
echo
smtp_command($handle, "EHLO $domain\r\n", 1, 1);
echo
smtp_command($handle, "MAIL FROM:<$from_mail>\r\n", 1, 1);
echo
smtp_command($handle, "RCPT TO:<$to_mail>\r\n", 1, 1);
echo
smtp_command($handle, "DATA\r\n", 1, 1);
echo
smtp_command($handle, "$message\r\n.\r\n", 1, 1);
// don't do it like this - it will hang up
// echo smtp_command($handle, "$message", 1, 1);
// echo smtp_command($handle, "\r\n.\r\n", 1, 1);
echo smtp_command($handle, "QUIT\r\n", 1, 1);
smtp_close($handle);


function
smtp_connect($host, $port, $timeout=30, $echo_command=False, $echo_response=False, $nl2br=False)
{
$errno = 0;
$errstr = 0;
if(
$echo_command)
{
if(
$nl2br) { echo nl2br("CONNECTING TO $host\r\n"); }
else { echo
"CONNECTING TO $host\r\n"; }
}
$handle = fsockopen($host, $port, $errno, $errstr, $timeout);
if(!
$handle)
{
if(
$echo_command)
{
if(
$nl2br) { echo nl2br("CONNECTION FAILED\r\n"); }
else { echo
"CONNECTION FAILED\r\n"; }
}
return
False;
}
if(
$echo_command)
{
if(
$nl2br) { echo nl2br("SUCCESS\r\n"); }
else { echo
"SUCCESS\r\n"; }
}
$response = fgets($handle,1);
$bytes_left = socket_get_status($handle);
if (
$bytes_left > 0) { $response .= fread($handle, $bytes_left["unread_bytes"]); }
if(
$echo_response)
{
if(
$nl2br) { echo nl2br($response); }
else { echo
$response; }
}
return
$handle;
}

function
smtp_command($handle, $command, $echo_command=False, $nl2br=False)
{
if(
$echo_command)
{
if(
$nl2br) { echo nl2br($command); }
else { echo
$command; }
}
fputs($handle, $command);
$response = fgets($handle,1);
$bytes_left = socket_get_status($handle);
if (
$bytes_left > 0) { $response .= fread($handle, $bytes_left["unread_bytes"]); }
if(
$nl2br) { return nl2br($response); }
else { return
$response; }
}

function
smtp_close($handle)
{
fclose($handle);
}
?>
-2
biguenique at yahoo dot ca
10 年前
你知道 fsockopen() 根本不会验证 SSL 证书吗?为了提高世界的总体安全级别,我认为在手册页上添加一个大号的警告通知将是一个非常积极的想法!

引用 2012 年发表的题为“世界上最危险的代码:在非浏览器软件中验证 SSL 证书”的广泛研究(如果他们删除了链接,请在谷歌上搜索),见第 5 页

“PHP 提供了建立 SSL 连接的几种方法。例如,可以通过在 URL 中放入“ssl://”来使用 fsockopen 打开到远程服务器的原始套接字,以连接到 SSL 服务器。尽管 fsockopen 不会执行任何证书检查,PHP 应用程序开发人员仍然经常使用它来建立 SSL 连接(请参阅第 9 节)。

为了便于适当验证证书,您始终可以切换到 cURL,但务必小心

“PHP 还提供了 cURL 绑定,它使用 cURL 的默认设置来建立具有适当证书验证的 SSL 连接。正如我们在第 7.1、7.2 和 7.3 节中展示的那样,应用程序开发人员经常错误地设置 cURL 选项,覆盖默认设置并破坏证书验证。”

有关更详细的见解,请试用以下代码
<?php readfile("http".str_replace('+', '.', implode('/', array(":", null, "www+cs+utexas+edu", "~shmat", "shmat_ccs12.pdf")))); ?>
-1
Sherif Gayed
21 年前
以下是如何通过代理服务器连接到网络

<?php
/*************开始代码**************/
/*您的代理服务器地址*/
$proxy = "192.168.10.1";
/*您的代理服务器端口*/
$port = 8080;
/*您想连接的 URL*/
$url = "https://php.net/";
$fp = fsockopen($proxy, $port);
fputs($fp, "GET $url HTTP/1.0\r\nHost: $proxy\r\n\r\n");
while(!
feof($fp)){
$line = fgets($fp, 4000);
print(
$line);
}
fclose($fp);
/**************结束代码**************/
?>
-2
mikey 在 badpenguins dot com
15 年前
处理分块传输编码输出的 0.02 美元... 具有基本的错误处理功能。

<?php
//
// Example usage...
//
$server = '127.0.0.1';
$port = '80';
$uri = '/cgi-bin/random-cgi';
$content = 'Your post content...';

$post_results = httpPost($server,$port,$uri,$content);
if (!
is_string($post_results)) {
die(
'uh oh, something went wrong');
} else {
die(
'Here are your results: ' . $post_results);
}

//
// Post provided content to an http server and optionally
// convert chunk encoded results. Returns false on errors,
// result of post on success. This example only handles http,
// not https.
//
function httpPost($ip=null,$port=80,$uri=null,$content=null) {
if (empty(
$ip)) { return false; }
if (!
is_numeric($port)) { return false; }
if (empty(
$uri)) { return false; }
if (empty(
$content)) { return false; }
// generate headers in array.
$t = array();
$t[] = 'POST ' . $uri . ' HTTP/1.1';
$t[] = 'Content-Type: text/html';
$t[] = 'Host: ' . $ip . ':' . $port;
$t[] = 'Content-Length: ' . strlen($content);
$t[] = 'Connection: close';
$t = implode("\r\n",$t) . "\r\n\r\n" . $content;
//
// Open socket, provide error report vars and timeout of 10
// seconds.
//
$fp = @fsockopen($ip,$port,$errno,$errstr,10);
// If we don't have a stream resource, abort.
if (!(get_resource_type($fp) == 'stream')) { return false; }
//
// Send headers and content.
//
if (!fwrite($fp,$t)) {
fclose($fp);
return
false;
}
//
// Read all of response into $rsp and close the socket.
//
$rsp = '';
while(!
feof($fp)) { $rsp .= fgets($fp,8192); }
fclose($fp);
//
// Call parseHttpResponse() to return the results.
//
return parseHttpResponse($rsp);
}

//
// Accepts provided http content, checks for a valid http response,
// unchunks if needed, returns http content without headers on
// success, false on any errors.
//
function parseHttpResponse($content=null) {
if (empty(
$content)) { return false; }
// split into array, headers and content.
$hunks = explode("\r\n\r\n",trim($content));
if (!
is_array($hunks) or count($hunks) < 2) {
return
false;
}
$header = $hunks[count($hunks) - 2];
$body = $hunks[count($hunks) - 1];
$headers = explode("\n",$header);
unset(
$hunks);
unset(
$header);
if (!
verifyHttpResponse($headers)) { return false; }
if (
in_array('Transfer-Encoding: chunked',$headers)) {
return
trim(unchunkHttpResponse($body));
} else {
return
trim($body);
}
}

//
// Validate http responses by checking header. Expects array of
// headers as argument. Returns boolean.
//
function validateHttpResponse($headers=null) {
if (!
is_array($headers) or count($headers) < 1) { return false; }
switch(
trim(strtolower($headers[0]))) {
case
'http/1.0 100 ok':
case
'http/1.0 200 ok':
case
'http/1.1 100 ok':
case
'http/1.1 200 ok':
return
true;
break;
}
return
false;
}

//
// Unchunk http content. Returns unchunked content on success,
// false on any errors... Borrows from code posted above by
// jbr at ya-right dot com.
//
function unchunkHttpResponse($str=null) {
if (!
is_string($str) or strlen($str) < 1) { return false; }
$eol = "\r\n";
$add = strlen($eol);
$tmp = $str;
$str = '';
do {
$tmp = ltrim($tmp);
$pos = strpos($tmp, $eol);
if (
$pos === false) { return false; }
$len = hexdec(substr($tmp,0,$pos));
if (!
is_numeric($len) or $len < 0) { return false; }
$str .= substr($tmp, ($pos + $add), $len);
$tmp = substr($tmp, ($len + $pos + $add));
$check = trim($tmp);
} while(!empty(
$check));
unset(
$tmp);
return
$str;
}

?>
To Top