• 検索結果がありません。

ホスト、ポートに対してソケット

接続し、サーバとの間でデータを

送受信 

サーバ 

(IPv4/IPv6を問わず)任意のポートでソケット接続を待ち

受け、接続したクライアントとの

間でデータを送受信 

複数のソケットを生成する

デュアルスタック対応

サーバ

プロセス IPv6

IPv4

サーバ プログラム 接続

IPv6

IPv4

87

クライアントプログラムの ポイント

フォールバック:接続できない場合に別の 接続先への接続に切替える動作 

接続先アドレス情報をリストで取得し、順にたどる

Client

Web Server

www.example.jp DNS Server

www.example.jp IN AAAA 2001:db8:100::1 www.example.jp IN A 192.0.2.1

①名前解決問合せ www.example.jp

AAAA応答 2001:db8:100::1 A応答 192.0.2.1

HTTP通信(IPv6 2001:db8:100::1

192.0.2.1 2001:db8:ffff::1

198.51.100.1

HTTP通信(IPv4

フォールバック

コーディングの留意点

関数、データ型はIPv4/IPv6両対応のものを使用

する 

データ型:文字列型  関数: 

get̲dns̲record()  gethostbyaddr() 

ライブラリ、フィルタを用いて入力値検証、変換 

ライブラリ:Net̲IPv6 

フィルタ:FILTER̲VALIDATE̲IP

gethostbyname()

は IPv6 非対応

89

Sample2 処理フロー

ユーザ入力値から 


接続先アドレス(リスト)を 
 取得

接続先アドレス(リスト)に、

順にソケットを生成して接続

Sample2 コード解説

(1)

<?php

$IS_DEBUG = 0;

$host = filter_input(INPUT_GET, 'host');

$port = filter_input(INPUT_GET, 'port', FILTER_VALIDATE_INT);

if ($host && $port){

$addresses = array();

if ($host_addr = filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){

$addresses[0]['domain'] = AF_INET6;

$addresses[0]['address'] = $host_addr;

} elseif ($host_addr = filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){

$addresses[0]['domain'] = AF_INET;

$addresses[0]['address'] = $host_addr;

フィルタを用いて変数が アドレスか判断

91

Sample2 コード解説

(2)

} else {

$host_list = dns_get_record($host);

$size = sizeof($host_list);

for ($loopcnt = 0; $loopcnt < $size; $loopcnt++){

if ($host_list[$loopcnt]['type'] === 'AAAA'){

$addresses[$loopcnt]['domain'] = AF_INET6;

$addresses[$loopcnt]['address']

= $host_list[$loopcnt]['ipv6'];

} else {

$addresses[$loopcnt]['domain'] = AF_INET;

$addresses[$loopcnt]['address']

= $host_list[$loopcnt]['ip'];

} } }

$size = sizeof($addresses);

$message = "接続先ホスト名 " . $host . " ポート番号 " . $port . "<BR>\n";

ホスト名の場合には

DNS

から アドレスをリストで取得

リストの数だけ、アドレスを取得し接続先候補とする

■ IPv6

AAAA

レコード、

IPv4

A

レコードに格納

gethostbyname()は、

IPv6非対応

Sample2 コード解説

(3)

$connect_flag = 0;

for ($loopcnt = 0; $loopcnt < $size && $connect_flag === 0; $loopcnt++){

if (($socket = socket_create($addresses[$loopcnt]['domain'], SOCK_STREAM, SOL_TCP)) === FALSE){

$error_code = socket_last_error();

$error_msg = socket_strerror($error_code);

$message .= "connect to " . $addresses[$loopcnt]['address'] . "<BR>\n";

$message .= 'socket create error: [' . $error_code . '] ' . $error_msg . "<BR>\n";

} else {

$message .= 'socket connect (' . ($loopcnt +1) . ') : ' . $addresses[$loopcnt]

['address'] . " port: " . $port . "<BR>\n";

ソケット作る

93

Sample2 コード解説

(4)

if (socket_connect($socket, $addresses[$loopcnt]['address'], $port)){

$connect_flag = 1;

$response = socket_read($socket, 1024);

$message .= "サーバからのメッセージ:" . '<div style="margin: 10px">' .

$response . '</div>' . "<BR>\n";

} else {

$error_code = socket_last_error();

$error_msg = socket_strerror($error_code);

$message .= 'socket connect error: [' . $error_code . '] ' . $error_msg .

"<BR>\n";

}

socket_close($socket);

} }

} else {

$message = "接続先ホスト名 " . $host . " もしくはポート番号 " . $port . "が入力さ れていません";

}

?>

接続する

切断する

Sample2 コード解説

(5)

<html>

<head>

<meta charset="UTF-8">

<title>Socket通信クライアント(デュアルスタック版)</title>

</head>

<body>

<H1>Socket通信クライアント(デュアルスタック版)</H1>

<form action="<?php echo filter_input(INPUT_SERVER, 'PHP_SELF', FILTER_SANITIZE_URL)?>" method="GET">

接続先ホスト <input type='text' name='host' value='<?php echo $host; ?>'>

ポート番号 <input type='text' name='port'value='<?php echo $port; ?>'>

<input type="submit" value="実行する">

</form>

<HR>

4. Apple の IPv6 対応解説

95

今年5月の

Apple

アナウンス

2016/6/1 から、App Store に載せるアプリは、

IPv6-only

ネットワークで動 作しないといけない

ほとんどのアプリは何も

変更しなくて大丈夫なはず

もし、IPv4 固有の API IPア ドレスをハードコードしていた ら、(

Networking Overview

の)「

Supporting IPv6

関連したドキュメント