Socket(ソケット)でデータを送信・受信 - fsockopen、POST、GET
2008-12-14
Socket(ソケット)でデータを送信・受信する方法。
Socket(ソケット)でデータを送信・受信
PHPでは、fsockopen() を使って、Socket の処理を行なう。
リクエストする各値は、\n ではなく \r\n で改行を行なう。
POSTやGETで渡す値は、リクエストヘッダの後、2回改行後、付け加える。
サンプルは、HTTP/1.1だが、HTTP/1.0でも基本的に書き方は同じ。
HTTP/1.1の場合は、Connection: Close がないと接続を維持するため、応答が遅くなる。
1回のリクエスト後、即接続を終了したい場合は、Connection: Close を書く。
フォームのデータを送信する場合は、Content-Type: application/x-www-form-urlencoded 。
以下、サンプル。
//URLからホスト名、パス、クエリを取得
//$host = "www.sample.com";
//$path = "/data/sample.php?a=12";
$target_url = "http://www.sample.com/data/sample.php?a=12";
$url_array = parse_url($target_url);
$port = 80;
if(isset($url_array['query'])){
$query = "?" . $url_array['query'];
}
$host = $url_array['host'];
$path = $url_array['path'] . $query;
if($path === ""){
$path = "/";
}
$params = "name=" . urlencode("名前")
. "&title=" . urlencode("タイトル")
. "&useragent=" . $_SERVER['HTTP_USER_AGENT'];
$results = send_socket($host, $port, $path, $params);
echo $results;
//送信関数
function send_socket($host, $port, $path, $param){
$data = '';
$sock = fsockopen($host, $port);
$request = "POST " . $path . " HTTP/1.1\r\n"
. "Host: " . $host . "\r\n"
. "Content-Type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($param) . "\r\n"
. "User-Agent: MSIE7.0\r\n"
. "Connection: Close\r\n"
. "\r\n"
. $param . "\r\n";
if(!$sock){
$data = 'socket error:' . $host;
}else{
fputs($sock, $request);
while(!feof($sock)){
$data .= fgets($sock);
}
fclose($sock);
}
return $data;
}
上記 $params は、http_build_query() を使って以下のように書ける。
$params = array('name' => urlencode("名前"),
'title' => urlencode("タイトル"),
'useragent' => $_SERVER['HTTP_USER_AGENT'],
);
$results = send_socket($host, $port, $path, http_build_query($params));
PING送信
ブログなどでよく使われるPINGサーバへのPINGの送信は、上記サンプルで $request の部分を以下のようにする。
$request = "POST " . $path . " HTTP/1.1\r\n"
. "Host: " . $host . "\r\n"
. "Content-Type: text/xml\r\n"
. "Content-Length: " . strlen($param) . "\r\n"
. "User-Agent: MSIE7.0\r\n"
. "Connection: Close\r\n"
. "\r\n"
. $param . "\r\n";
また、送信するデータ $params は、以下の書式。
$params = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
. "<methodCall>\r\n"
. "<methodName>weblogUpdates.ping</methodName>\r\n"
. "<params>\r\n"
. "<param><value>自分のサイトのタイトル</value></param>\r\n"
. "<param><value>自分のサイトのURL</value></param>\r\n"
. "</params>\r\n"
. "</methodCall>";