UPnPでポート開放
UPnPでポート開放
Winsockを使ってチャットを作成しています。
ローカルネットワーク上では自分のPC二台でやり取りができたのですが
インターネットを通してやり取りをするとなるとルーターからポートを開放しなければならないので
UPnPを使用してポートを開放したいです。
自分がサーバーを起動し、ユーザーがクライアントとなれば、私がルーターにアクセスして手動で開放してもいいのですが、
配布したりしてサーバーを私以外の人が起動するときに手間を取らせないためにソフト側でポートの開放をしたいです。
http://ohwhsmm7.blog28.fc2.com/blog-entry-15.html
こちらのページを見つけたのですが、いまいちピンとこないので
他にいいやり方が載ってるページ、もしくはいいやり方を教えてください。
ローカルネットワーク上では自分のPC二台でやり取りができたのですが
インターネットを通してやり取りをするとなるとルーターからポートを開放しなければならないので
UPnPを使用してポートを開放したいです。
自分がサーバーを起動し、ユーザーがクライアントとなれば、私がルーターにアクセスして手動で開放してもいいのですが、
配布したりしてサーバーを私以外の人が起動するときに手間を取らせないためにソフト側でポートの開放をしたいです。
http://ohwhsmm7.blog28.fc2.com/blog-entry-15.html
こちらのページを見つけたのですが、いまいちピンとこないので
他にいいやり方が載ってるページ、もしくはいいやり方を教えてください。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: UPnPでポート開放
あぁ、その問題がありましたね。。。softya(ソフト屋) さんが書きました:UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
忘れていました。
まだ考えていないのですがそちらを先に考えた方がよろしいでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
どうやって、サーバーやクライアントのIPアドレスを相手に渡すかは重要な問題ですので、UPnPとは別に解決する必要があります。みなみ さんが書きました:あぁ、その問題がありましたね。。。softya(ソフト屋) さんが書きました:UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
忘れていました。
まだ考えていないのですがそちらを先に考えた方がよろしいでしょうか?
ルータが間に挟まっている場合は、PCがグローバルIPアドレスを調べるためには外部サーバで調べるしか有りません。
その外部サーバは自分で用意するか、公開されているサーバを利用条件の許される範囲内で利用する必要があります。
出来れば、サーバーとクライアントのマッチングをする公開マッチングサーバーを用意したほうがいろんな人に遊んでもらうには良いと思います。
マッチング後は、各々のサーバーとクライアント間で通信してもらいます。
そういう仕組にしないと、お互いにメールアドレスを知る知人同士でしか使えないと思いますよ。
それとUPnPのコードですが、私もUPnPはやったことはないですが、このCOMコードは難しくないのでよく分からなくても試してみてはどうでしょうか?
char *ip = "192.168.xxx.xxx"; <- 自分のPCのローカルIPアドレス
BSTR description = SysAllocString( L"????" ); <- ここはポートマッピングに登録する名前。適当で良いと思います。
int port = xxxx; <- 開放するポート番号
を入力するだけで動くと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: UPnPでポート開放
レンタルサーバーで掲示板を運営したりしているのでsoftya(ソフト屋) さんが書きました:どうやって、サーバーやクライアントのIPアドレスを相手に渡すかは重要な問題ですので、UPnPとは別に解決する必要があります。みなみ さんが書きました:あぁ、その問題がありましたね。。。softya(ソフト屋) さんが書きました:UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
忘れていました。
まだ考えていないのですがそちらを先に考えた方がよろしいでしょうか?
ルータが間に挟まっている場合は、PCがグローバルIPアドレスを調べるためには外部サーバで調べるしか有りません。
その外部サーバは自分で用意するか、公開されているサーバを利用条件の許される範囲内で利用する必要があります。
出来れば、サーバーとクライアントのマッチングをする公開マッチングサーバーを用意したほうがいろんな人に遊んでもらうには良いと思います。
マッチング後は、各々のサーバーとクライアント間で通信してもらいます。
そういう仕組にしないと、お互いにメールアドレスを知る知人同士でしか使えないと思いますよ。
それとUPnPのコードですが、私もUPnPはやったことはないですが、このCOMコードは難しくないのでよく分からなくても試してみてはどうでしょうか?
char *ip = "192.168.xxx.xxx"; <- 自分のPCのローカルIPアドレス
BSTR description = SysAllocString( L"????" ); <- ここはポートマッピングに登録する名前。適当で良いと思います。
int port = xxxx; <- 開放するポート番号
を入力するだけで動くと思います。
そこにソケットで接続してIPを取得するというやり方がいいかな?と考えました。
どうでしょうか?
このコードVC++2010でも使えるのでしょうか?
エラーばかり出てどこを直したらいいのかわからなくて困っています。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
オリジナルのCGIが使えるなら問題ないと思います。みなみ さんが書きました:レンタルサーバーで掲示板を運営したりしているので
そこにソケットで接続してIPを取得するというやり方がいいかな?と考えました。
どうでしょうか?
とりあえず、ヘッダがなかったので加えたのとこちらの都合の良いアドレスなどが埋めこんであります。みなみ さんが書きました:このコードVC++2010でも使えるのでしょうか?
エラーばかり出てどこを直したらいいのかわからなくて困っています。
動作テストしましたが、UPnPはうまく動いたようです。
「UPnPCJ」 ← 動作確認ツール。UPnPツールなわけですが。
http://www.geocities.jp/umemasu2010/upnpcj/
インストール版で出来る"UPnPCJ (手動開放)"で起動して、⑬PortMapで確認。
#include <windows.h>
#include <Natupnp.h>
int main()
{
// まずCOMの初期化
::CoInitialize( NULL );
// インスタンス取得
IUPnPNAT *nat;
::CoCreateInstance( CLSID_UPnPNAT, NULL, CLSCTX_ALL, IID_IUPnPNAT, (void **)&nat );
// ポートマッピングのリスト取得
IStaticPortMappingCollection *maps = NULL;
nat->get_StaticPortMappingCollection( &maps );
// アドレスと名前を登録できる形式に変更
char *ip = "192.168.1.17"; //<- 自分のIPアドレス
WCHAR localIPWideString[ 16 ];
MultiByteToWideChar( CP_ACP, 0, ip, -1, localIPWideString, 16 );
BSTR localIPBstr = SysAllocString( localIPWideString );
BSTR proto = SysAllocString( L"TCP" ); //<- TCP/IPで登録する
BSTR description = SysAllocString( L"UPNPXXX" ); //<- ここはポートマッピングに登録する名前
// ポートマッピング
int port = 19191; //<- 開放するポート番号
IStaticPortMapping *map;
maps->Add( port, proto, port, localIPBstr, VARIANT_TRUE, description, &map );
// BSTR の解放
SysFreeString( description );
SysFreeString( proto );
SysFreeString( localIPBstr );
// オブジェクト解放
map->Release();
maps->Release();
nat->Release();
// COMの終了
::CoUninitialize();
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: UPnPでポート開放
横から失礼いたします。
当方も先日までUPnPでのポート開放に
躓いていたのですが何とか形にできました。
が、次はP2P?部となる通信部分をどのようにすればよいのか
色々と試してみてはいるのですが通信ができません。
現状できているのは、ポートマッピングとそれに伴う
双方(2台)のPCのグローバルIPアドレス、サブネット、ローカルIPアドレス(各種ポート)
一通り、通信に必要そうな物は取得(設定)できているのですが
winsock2で単純に
SockAddr.sin_port = htons(port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
※上記port、addressは取りあえずです。
とお決まりの形ではだめのようで・・・。
どなたか助言可能であれば御助けください。
※開発環境は、Windows7 VC++2008(2010)Express
当方も先日までUPnPでのポート開放に
躓いていたのですが何とか形にできました。
が、次はP2P?部となる通信部分をどのようにすればよいのか
色々と試してみてはいるのですが通信ができません。
現状できているのは、ポートマッピングとそれに伴う
双方(2台)のPCのグローバルIPアドレス、サブネット、ローカルIPアドレス(各種ポート)
一通り、通信に必要そうな物は取得(設定)できているのですが
winsock2で単純に
SockAddr.sin_port = htons(port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
※上記port、addressは取りあえずです。
とお決まりの形ではだめのようで・・・。
どなたか助言可能であれば御助けください。
※開発環境は、Windows7 VC++2008(2010)Express
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
別のトピックにされた方が良いかと思います。Mr.D さんが書きました:横から失礼いたします。
当方も先日までUPnPでのポート開放に
躓いていたのですが何とか形にできました。
が、次はP2P?部となる通信部分をどのようにすればよいのか
色々と試してみてはいるのですが通信ができません。
現状できているのは、ポートマッピングとそれに伴う
双方(2台)のPCのグローバルIPアドレス、サブネット、ローカルIPアドレス(各種ポート)
一通り、通信に必要そうな物は取得(設定)できているのですが
winsock2で単純に
SockAddr.sin_port = htons(port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
※上記port、addressは取りあえずです。
とお決まりの形ではだめのようで・・・。
どなたか助言可能であれば御助けください。
※開発環境は、Windows7 VC++2008(2010)Express
その時に、どうだめなのかの詳細や考えているP2Pのアルゴリズムの解説と出来ればコードをお貼りください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: UPnPでポート開放
わざわざコード書いていただきありがとうございます。softya(ソフト屋) さんが書きました:オリジナルのCGIが使えるなら問題ないと思います。みなみ さんが書きました:レンタルサーバーで掲示板を運営したりしているので
そこにソケットで接続してIPを取得するというやり方がいいかな?と考えました。
どうでしょうか?
とりあえず、ヘッダがなかったので加えたのとこちらの都合の良いアドレスなどが埋めこんであります。みなみ さんが書きました:このコードVC++2010でも使えるのでしょうか?
エラーばかり出てどこを直したらいいのかわからなくて困っています。
動作テストしましたが、UPnPはうまく動いたようです。
「UPnPCJ」 ← 動作確認ツール。UPnPツールなわけですが。
http://www.geocities.jp/umemasu2010/upnpcj/
インストール版で出来る"UPnPCJ (手動開放)"で起動して、⑬PortMapで確認。
#include <windows.h> #include <Natupnp.h> int main() { // まずCOMの初期化 ::CoInitialize( NULL ); // インスタンス取得 IUPnPNAT *nat; ::CoCreateInstance( CLSID_UPnPNAT, NULL, CLSCTX_ALL, IID_IUPnPNAT, (void **)&nat ); // ポートマッピングのリスト取得 IStaticPortMappingCollection *maps = NULL; nat->get_StaticPortMappingCollection( &maps ); // アドレスと名前を登録できる形式に変更 char *ip = "192.168.1.17"; //<- 自分のIPアドレス WCHAR localIPWideString[ 16 ]; MultiByteToWideChar( CP_ACP, 0, ip, -1, localIPWideString, 16 ); BSTR localIPBstr = SysAllocString( localIPWideString ); BSTR proto = SysAllocString( L"TCP" ); //<- TCP/IPで登録する BSTR description = SysAllocString( L"UPNPXXX" ); //<- ここはポートマッピングに登録する名前 // ポートマッピング int port = 19191; //<- 開放するポート番号 IStaticPortMapping *map; maps->Add( port, proto, port, localIPBstr, VARIANT_TRUE, description, &map ); // BSTR の解放 SysFreeString( description ); SysFreeString( proto ); SysFreeString( localIPBstr ); // オブジェクト解放 map->Release(); maps->Release(); nat->Release(); // COMの終了 ::CoUninitialize(); }
#include <windows.h>
#include <Natupnp.h>
#include <objbase.h>
#include <oleauto.h>
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")
int main()
{
// まずCOMの初期化
::CoInitialize( NULL );
// インスタンス取得
IUPnPNAT *nat;
::CoCreateInstance( CLSID_UPnPNAT, NULL, CLSCTX_ALL, IID_IUPnPNAT, (void **)&nat );
// ポートマッピングのリスト取得
IStaticPortMappingCollection *maps = NULL;
nat->get_StaticPortMappingCollection( &maps );
// アドレスと名前を登録できる形式に変更
char *ip = "192.168.11.2"; //<- 自分のIPアドレス
WCHAR localIPWideString[ 16 ];
MultiByteToWideChar( CP_ACP, 0, ip, -1, localIPWideString, 16 );
BSTR localIPBstr = SysAllocString( localIPWideString );
BSTR proto = SysAllocString( L"TCP" ); //<- TCP/IPで登録する
BSTR description = SysAllocString( L"TOOL" ); //<- ここはポートマッピングに登録する名前
// ポートマッピング
int port = 57630; //<- 開放するポート番号
IStaticPortMapping *map;
maps->Add( port, proto, port, localIPBstr, VARIANT_TRUE, description, &map );
// BSTR の解放
SysFreeString( description );
SysFreeString( proto );
SysFreeString( localIPBstr );
// オブジェクト解放
map->Release();
maps->Release();
nat->Release();
// COMの終了
::CoUninitialize();
}
実行ファイルを起動してもポートの開放がされません。
ipconfigで自分のIPアドレスは確認しました。
ルーターの設定でUPnPは許可にしています。
どこがおかしいのでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
どの様にしてポートの開放を確認されたのでしょうか?みなみ さんが書きました:このようにしてコンパイルは通ったのですが
実行ファイルを起動してもポートの開放がされません。
ipconfigで自分のIPアドレスは確認しました。
ルーターの設定でUPnPは許可にしています。
それとTCP/UDPのプロトコルはあっていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: UPnPでポート開放
ルーターにアクセスして確認しました。softya(ソフト屋) さんが書きました:どの様にしてポートの開放を確認されたのでしょうか?みなみ さんが書きました:このようにしてコンパイルは通ったのですが
実行ファイルを起動してもポートの開放がされません。
ipconfigで自分のIPアドレスは確認しました。
ルーターの設定でUPnPは許可にしています。
それとTCP/UDPのプロトコルはあっていますか?
TCP/UDPのプロトコルがあっているかどうかとは
どういう意味でしょうか?
http://gyazo.com/3814e4ed8fe797207c8037f329e0a370.png
これがルーターにアクセスしたときの画像なのですが、
手動でポートを開放すると
「ポート変換登録情報」というところに開放されているポートが書かれているのですが
今回のアプリを実行したところ、ここに登録されることはなかったです。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
ルータでは確認できないみたいなので、UPnPCと言うツールをご紹介しました。みなみ さんが書きました:ルーターにアクセスして確認しました。
つまり、ルータには登録されません(恒久な登録情報ではないためです)
UPnPのコードですがTCPで通信するポートを開けています。みなみ さんが書きました:TCP/UDPのプロトコルがあっているかどうかとは
どういう意味でしょうか?
もし、通信でUDPを使っていたらポートが空いていない状態です。
なので、TCP/UDPのどちらの通信を使われているかお聞きしました。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: UPnPでポート開放
横から失礼します。
何から何まで 同じ境遇で少し怖いのですが...
上記のソースの場合だと、
現状登録されているポート周りの判定等々が無い等の問題点が幾つか挙げられます。
※当方は、違う方法で行っているためその点も考慮して作っております。
あと上記のソースに追記で、「maps->Remove(port, proto);」を追加して閉鎖もおすすめ致します。
もう一つ、ルーターのTOP画面に「ユーティリティー機能」という文言と一緒に
「ネットワークサービスの一覧を表示」というボタンがあると思います。
そちらを押して頂くと、上記ソースを起動後であれば
|パソコン名 |IPアドレス |サービス |
|名称不明 |192.168.***.***|□□ |
|(**:**:**:**:**:**) | | |
の自分のローカルIPアドレスの右側に ファミコンのコントローラーみたいなアイコンが追加されます。
そのコントローラーが出ているIPに対しては、ポートマッピング成功です。
何から何まで 同じ境遇で少し怖いのですが...
上記のソースの場合だと、
現状登録されているポート周りの判定等々が無い等の問題点が幾つか挙げられます。
※当方は、違う方法で行っているためその点も考慮して作っております。
あと上記のソースに追記で、「maps->Remove(port, proto);」を追加して閉鎖もおすすめ致します。
もう一つ、ルーターのTOP画面に「ユーティリティー機能」という文言と一緒に
「ネットワークサービスの一覧を表示」というボタンがあると思います。
そちらを押して頂くと、上記ソースを起動後であれば
|パソコン名 |IPアドレス |サービス |
|名称不明 |192.168.***.***|□□ |
|(**:**:**:**:**:**) | | |
の自分のローカルIPアドレスの右側に ファミコンのコントローラーみたいなアイコンが追加されます。
そのコントローラーが出ているIPに対しては、ポートマッピング成功です。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: UPnPでポート開放
ポート判定は確かに無いですね。Mr.D さんが書きました:横から失礼します。
何から何まで 同じ境遇で少し怖いのですが...
上記のソースの場合だと、
現状登録されているポート周りの判定等々が無い等の問題点が幾つか挙げられます。
※当方は、違う方法で行っているためその点も考慮して作っております。
あと上記のソースに追記で、「maps->Remove(port, proto);」を追加して閉鎖もおすすめ致します。
もう一つ、ルーターのTOP画面に「ユーティリティー機能」という文言と一緒に
「ネットワークサービスの一覧を表示」というボタンがあると思います。
そちらを押して頂くと、上記ソースを起動後であれば
|パソコン名 |IPアドレス |サービス |
|名称不明 |192.168.***.***|□□ |
|(**:**:**:**:**:**) | | |
の自分のローカルIPアドレスの右側に ファミコンのコントローラーみたいなアイコンが追加されます。
そのコントローラーが出ているIPに対しては、ポートマッピング成功です。
それと今のコードはmaps->Remove(port, proto);を入れてしまうと単なる接続・閉鎖するだけのプログラムになってしまいますので、実際のプログラムに入れ込むときに必要なことだけを理解してください。UPnPと実際のプログラムを一体化させると思いますので。
それと家のBBR-4HGは「ネットワークサービスの一覧を表示」は古いのでないんですよね。ファームは最新なんですが。
最近のは便利なのが付いてますね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。