socket模拟post表单

 
更多

post的本质就是发送给目的程序一个标志为post的协议串如下:

  POST /目的程序 HTTP/1.1
  Accept: */*
  Referer: http://www.phpiask.com
  Accept-Language: zh-cn,en-us;q=0.5
  Content-Type: application/x-www-form-urlencoded
  User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
  Host: 要发送到的主机地址
  Content-Length: 发送数据的长度
  Pragma: no-cache
  Cache-Control: no-cache
  username=php&password=iask //post发送的数据

我想大家对form的post方法应该是最熟悉不过了,例如我们想吧用户名和密码发送给某个页面的时候,点击有两个文本域的表单的提交按钮,这个表单发送到action程序的就是以上数据。知道了这一点我想就不难了。

这时候我们只需要用php的socket打开一个端口,例如80端口,把以上信息利用这个端口发送给目的程序就行了。

我们如何在一个端口上建立一个socket信道呢?

在PHP中是如此简单呢!

fsockopen(主机名称,端口号码,错误号的接受变量,错误提示的接受变量,超时时间)

主机名称就是你需要发送数据的目的地;

端口号就是这个目的程序会在哪个端口等着你的数据;

错误号的接受变量,这个是如果建立socket不成功的时候返回的错误编号;

错误提示的变量,是错误的时候返回的错误提示信息;

超时时间,就是post数据之后如果对方没有回应信息,等待的最长时间。

如果不出意外(你正确的设置fsockopen()函数的参数)的话,一个socket信道现在已经打开了,我们下一步需要做的就是,通过这个打开的信道把post请求协议发给目的程序,这时候可以使用fwrite或者fputs函数中的任意一个,把post的请求格式发给fsockopen()打开的句柄,这时候一个伟大的socket模拟的post请求就诞生了。顺便说一下啊:

你发送的时候可不能把我的post请求格式直接ctrl + V过去,你没看见里面的汉字等你自己去填写的吗?

以上是文字的描述,如果大家觉得说的非常垃圾,非常没有说服力的话,下边有一个现成的程序片段,大家可以看看。

  $port = $url['port'] ? $url['port'] : 80;
  $fp = fsockopen($url['host'], $port, $errno, $errstr,10);
  if (!$fp) return "在主机: $url[host] $port 打开socket失败,失败原因是: $errno - $errstr";
  fputs($fp, sprintf("POST %s%s%s HTTP/1.0\r\n", $url['path'], $url['query'] ? "?" : "", $url['query']));
  fputs($fp, "Host:".$url['host']."\r\n");
  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
  fputs($fp, "Content-length: " . strlen($encoded) . "\r\n");
  fputs($fp, "Connection: close\r\n\r\n");
  fputs($fp, "$encoded\\n");

对了还是顺便说一下吧,fgets($fp,1024);这个可以得到返回值的哦!!已经有不止一个人问过我咋接受返回了!!

Demo
send.php

<?
/*
 * Socket模拟post表单
 * 绝缘体 2012/04/08
 * */
function Stocket_Post($Url, $Data) {
	if (empty ( $Url ) || empty ( $Data )) {
		return false;
	}
	$Url = parse_url ( $Url );

	$Encoded = "";
	while ( list ( $k, $v ) = each ( $Data ) ) {
		$Encoded .= ($Encoded ? "&" : "");
		$Encoded .= rawurlencode ( $k ) . "=" . rawurlencode ( $v );
	}

	$fp = fsockopen ( $Url ['host'], ! empty ( $Url ['port'] ) ? $Url ['port'] : 80 );
	if (! $fp) {
		//echo "Failed to open socket to $Url[host]";
		return false;
	}
	$Post = @sprintf ( "POST %s%s%s HTTP/1.0\n", $Url ['path'], isset ( $Url ['query'] ) ? "?" : "", $Url ['query'] );
	$Post .= "Host: " . $Url ['host'] . "\n";
	$Post .= "Content-type: application/x-www-form-urlencoded\n";
	$Post .= "Content-length: " . strlen ( $Encoded ) . "\n";
	$Post .= "Connection: close\n\n";
	$Post .= $Encoded . "\n";
	if (fputs ( $fp, $Post )) {
		return true;
	}
	return false;
}

/**
 * Curl版本
 * 使用方法:
 * $post_string = "app=request&version=beta";
 * request_by_curl('http://facebook.cn/restServer.php',$post_string);
 */
function request_by_curl($remote_server, $post_string) {
	$ch = curl_init ();
	curl_setopt ( $ch, CURLOPT_URL, $remote_server );
	curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_string );
	curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
	curl_setopt ( $ch, CURLOPT_USERAGENT, "Jimmy's CURL Example beta" );
	$data = curl_exec ( $ch );
	curl_close ( $ch );
	return $data;
}
session_start();
$Data = array ("time" => date('Y-m-d H:i:s'), "sid" => session_id() );
var_dump ( Stocket_Post ( "http://localhost:84/socket/post.php", $Data ) );

?>

post.php

<?php
//文件写入函数
function F_Write($File, $Data) {
	if (! is_dir ( dirname ( $File ) )) {
		if (! CreateFolder ( dirname ( $File ) )) {
			return false;
		}
	}
	@$fp = fopen ( $File, 'a' );
	if (! @fwrite ( $fp, $Data . "------------------------------------------\r\n" )) {
		return false;
	}
	return true;
}

//创建多级目录
function CreateFolder($path) {
	$Rs = false;
	if (! file_exists ( $path )) {
		createFolder ( dirname ( $path ) );
		if (@mkdir ( $path, 0777 ))
			$Rs = true;
	}
	return $Rs;
}

if (! empty ( $_POST )) {
	$Data = date ( 'Ymd H:i:s' ) . "\n\r";
	$Data .= var_export ( $_POST, TRUE ) . "\n\r";
	$File = dirname ( __FILE__ ) . '/Log/Post/' . date ( 'Ymd' ) . '.log';
	F_Write ( $File, $Data );
} else {
	$Data = date ( 'Ymd H:i:s' ) . "\n\r";
	$File = dirname ( __FILE__ ) . '/Log/Post/' . date ( 'Ymd' ) . '.log';
	F_Write ( $File, $Data );
}

?>

参考:http://www.oschina.net/code/snippet_127872_6370

打赏

本文固定链接: https://www.cxy163.net/archives/403 | 绝缘体

该日志由 绝缘体.. 于 2012年04月08日 发表在 PHP 分类下,
原创文章转载请注明: socket模拟post表单 | 绝缘体
【上一篇】
【下一篇】

报歉!评论已关闭.