UPnPによるポートマップ
    Natを越えないとP2P通信できない
    UPnPを使えば、TCPでもNat越えができる
Socketを使う事で簡単に、インターネットを利用したアプリケーションが作成する事ができます。プラウザーとかメーラーとかです。
しかし、P2Pアプリケーションを作る場合は、もう一つ考慮しなくてはならない事があります。それが、「Nat越え」です。
P2Pアプリとして、必ず満たさなければならない条件は、何でしょうか? それは、ユーザーが所有する端末同士が直接データ通信をできる事です。P2Pの定義そのものですね。 これができません。
Nat越えをする方法はいくつかあります。本章では、UPnPを用いてNat越えをする方法について解説したいと思います。

Global IP が必要

P2P通信するするためには、相手に自分の「IPアドレス」と「Port番号」を教える。必要ががあります。しかし、Nat越えの問題を解決しないと、これができません。
ご家庭からインターネットにアクセスする場合、ルーターというデバイスを利用しています。 ルーターは、ルータに接続している端末に 「Private IP」 を割り振ります。
1
>> netstat
Copied!
とコマンドを入力してみましょう。「192.168.100.1」といったアドレスが端末に割り振られている事が確認できます。このアドレスを相手に伝えても、通信ができません。

ルータから教えてもらおう

しかし、ルーターからインターネットに接続できているという事は、「Global IP」をルーターは持っているから通信できるのです。つまり、ルーターは「Global IP」をルーターは知っている。しかし、ルーターを利用している端末は「Global IP」をしらないという問題があります。

UPnPを用いてPort Mappingをしよう

UPNPを実現するには、UDPとTCPを用いて通信できる必要があります。 具体的には、
    UDP Multicast を利用して、使用中のルーターに、ポートマッピングを依頼するためのアドレスを教えてもらう。
    TCP を使って、教えてもらったアドレスからポートマッピングの依頼をだす。
といった事をします。実際にTryしてみましょう。

依頼先を調べる

UDPで以下のメッセージを通知する
1
M-SEARCH * HTTP/1.1
2
MX: 3
3
HOST: 239.255.255.250:1900
4
MAN: "ssdp:discover"
5
ST: urn:schemas-upnp-org:service:WANIPConnection:1
Copied!
もしもルーターが存在していれば、以下のような返答があります。
1
HTTP/1.1 200 OK
2
CACHE-CONTROL: max-age=1800
3
ST: urn:schemas-upnp-org:service:WANIPConnection:1
4
USN: uuid:E8088BD3-E808-8BD3-A042-E8088BD3A042::urn:schemas-upnp-org:service:WANIPConnection:1
5
EXT:
6
SERVER: E588 UPnP/1.0 MiniUPnPd/1.6
7
LOCATION: http://192.168.100.1:54616/rootDesc.xml
8
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
9
01-NLS: 1
10
BOOTID.UPNP.ORG: 1
11
CONFIGID.UPNP.ORG: 1337
12
DATE: Sun, 14 Sep 2014 00:42:14 GMT
Copied!
LOCATIONで指定されたアドレスのXMLファイルのタグの中に依頼先のアドレスが記載されています。このアドレスへ依頼をだせば、インターネットから、あなたの端末へアクセスできるようになります。

外部の端末から見えているアドレスを聞く

1
POST 192.168.100.1 HTTP/1.1
2
Host: 192.168.100.1
3
Connection: close
4
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"
5
Content-Length: 324
Copied!
成功すると、以下のような返信を受け取ります。
1
HTTP/1.1 200 OK
2
Content-Type: text/xml; charset="utf-8"
3
Connection: close
4
Content-Length: 360
5
Server: E588 UPnP/1.0 MiniUPnPd/1.6
6
EXT:
7
DATE: Sun, 14 Sep 2014 01:46:07 GMT
Copied!

ポートマッピングの依頼をだす

1
POST 192.168.100.1 HTTP/1.1
2
Host: 192.168.100.1
3
Connection: close
4
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
5
Content-Length: 629
6
7
<?xml version="1.0"?>
8
<SOAP-ENV:Envelope xmlns:SOAP-ENV:="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
9
<SOAP-ENV:Body><m:AddPortMapping xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1">
10
<NewRemoteHost></NewRemoteHost>
11
<NewExternalPort>48083</NewExternalPort>
12
<NewProtocol>TCP</NewProtocol>
13
<NewInternalPort>8083</NewInternalPort>
14
<NewInternalClient>192.168.100.100</NewInternalClient>
15
<NewEnabled>1</NewEnabled>
16
<NewPortMappingDescription>test</NewPortMappingDescription>
17
<NewLeaseDuration>0</NewLeaseDuration>
18
</m:AddPortMapping></SOAP-ENV:Body>
19
</SOAP-ENV:Envelope>
Copied!
1
HTTP/1.1 200 OK
2
Content-Type: text/xml; charset="utf-8"
3
Connection: close
4
Content-Length: 263
5
Server: E588 UPnP/1.0 MiniUPnPd/1.6
6
EXT:
7
DATE: Sun, 14 Sep 2014 01:39:27 GMT
8
9
<?xml version="1.0"?>
10
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
11
<s:Body>
12
<u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"/>
13
</s:Body>
14
</s:Envelope>
Copied!
Kyorohiro work
Last modified 3yr ago