ページ 1 / 1
UPnPでポート開放
Posted: 2011年5月16日(月) 18:18
by みなみ
Winsockを使ってチャットを作成しています。
ローカルネットワーク上では自分のPC二台でやり取りができたのですが
インターネットを通してやり取りをするとなるとルーターからポートを開放しなければならないので
UPnPを使用してポートを開放したいです。
自分がサーバーを起動し、ユーザーがクライアントとなれば、私がルーターにアクセスして手動で開放してもいいのですが、
配布したりしてサーバーを私以外の人が起動するときに手間を取らせないためにソフト側でポートの開放をしたいです。
http://ohwhsmm7.blog28.fc2.com/blog-entry-15.html
こちらのページを見つけたのですが、いまいちピンとこないので
他にいいやり方が載ってるページ、もしくはいいやり方を教えてください。
Re: UPnPでポート開放
Posted: 2011年5月16日(月) 22:57
by softya(ソフト屋)
UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
Re: UPnPでポート開放
Posted: 2011年5月16日(月) 23:41
by みなみ
softya(ソフト屋) さんが書きました:UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
あぁ、その問題がありましたね。。。
忘れていました。
まだ考えていないのですがそちらを先に考えた方がよろしいでしょうか?
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 00:12
by softya(ソフト屋)
みなみ さんが書きました:softya(ソフト屋) さんが書きました:UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
あぁ、その問題がありましたね。。。
忘れていました。
まだ考えていないのですがそちらを先に考えた方がよろしいでしょうか?
どうやって、サーバーやクライアントのIPアドレスを相手に渡すかは重要な問題ですので、UPnPとは別に解決する必要があります。
ルータが間に挟まっている場合は、PCがグローバルIPアドレスを調べるためには外部サーバで調べるしか有りません。
その外部サーバは自分で用意するか、公開されているサーバを利用条件の許される範囲内で利用する必要があります。
出来れば、サーバーとクライアントのマッチングをする公開マッチングサーバーを用意したほうがいろんな人に遊んでもらうには良いと思います。
マッチング後は、各々のサーバーとクライアント間で通信してもらいます。
そういう仕組にしないと、お互いにメールアドレスを知る知人同士でしか使えないと思いますよ。
それとUPnPのコードですが、私もUPnPはやったことはないですが、このCOMコードは難しくないのでよく分からなくても試してみてはどうでしょうか?
char *ip = "192.168.xxx.xxx"; <- 自分のPCのローカルIPアドレス
BSTR description = SysAllocString( L"????" ); <- ここはポートマッピングに登録する名前。適当で良いと思います。
int port = xxxx; <- 開放するポート番号
を入力するだけで動くと思います。
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 00:33
by みなみ
softya(ソフト屋) さんが書きました:みなみ さんが書きました:softya(ソフト屋) さんが書きました:UPnP以前の質問ですが、サーバーと成るPCのIPアドレスはどうやって相手の方に通知する予定でしょうか?
あぁ、その問題がありましたね。。。
忘れていました。
まだ考えていないのですがそちらを先に考えた方がよろしいでしょうか?
どうやって、サーバーやクライアントのIPアドレスを相手に渡すかは重要な問題ですので、UPnPとは別に解決する必要があります。
ルータが間に挟まっている場合は、PCがグローバルIPアドレスを調べるためには外部サーバで調べるしか有りません。
その外部サーバは自分で用意するか、公開されているサーバを利用条件の許される範囲内で利用する必要があります。
出来れば、サーバーとクライアントのマッチングをする公開マッチングサーバーを用意したほうがいろんな人に遊んでもらうには良いと思います。
マッチング後は、各々のサーバーとクライアント間で通信してもらいます。
そういう仕組にしないと、お互いにメールアドレスを知る知人同士でしか使えないと思いますよ。
それとUPnPのコードですが、私もUPnPはやったことはないですが、このCOMコードは難しくないのでよく分からなくても試してみてはどうでしょうか?
char *ip = "192.168.xxx.xxx"; <- 自分のPCのローカルIPアドレス
BSTR description = SysAllocString( L"????" ); <- ここはポートマッピングに登録する名前。適当で良いと思います。
int port = xxxx; <- 開放するポート番号
を入力するだけで動くと思います。
レンタルサーバーで掲示板を運営したりしているので
そこにソケットで接続してIPを取得するというやり方がいいかな?と考えました。
どうでしょうか?
このコードVC++2010でも使えるのでしょうか?
エラーばかり出てどこを直したらいいのかわからなくて困っています。
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 01:32
by softya(ソフト屋)
みなみ さんが書きました:レンタルサーバーで掲示板を運営したりしているので
そこにソケットで接続してIPを取得するというやり方がいいかな?と考えました。
どうでしょうか?
オリジナルのCGIが使えるなら問題ないと思います。
みなみ さんが書きました:このコード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();
}
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 11:33
by 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
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 12:59
by softya(ソフト屋)
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のアルゴリズムの解説と出来ればコードをお貼りください。
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 23:32
by みなみ
softya(ソフト屋) さんが書きました:みなみ さんが書きました:レンタルサーバーで掲示板を運営したりしているので
そこにソケットで接続してIPを取得するというやり方がいいかな?と考えました。
どうでしょうか?
オリジナルのCGIが使えるなら問題ないと思います。
みなみ さんが書きました:このコード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は許可にしています。
どこがおかしいのでしょうか?
Re: UPnPでポート開放
Posted: 2011年5月17日(火) 23:56
by softya(ソフト屋)
みなみ さんが書きました:このようにしてコンパイルは通ったのですが
実行ファイルを起動してもポートの開放がされません。
ipconfigで自分のIPアドレスは確認しました。
ルーターの設定でUPnPは許可にしています。
どの様にしてポートの開放を確認されたのでしょうか?
それとTCP/UDPのプロトコルはあっていますか?
Re: UPnPでポート開放
Posted: 2011年5月18日(水) 12:53
by みなみ
softya(ソフト屋) さんが書きました:みなみ さんが書きました:このようにしてコンパイルは通ったのですが
実行ファイルを起動してもポートの開放がされません。
ipconfigで自分のIPアドレスは確認しました。
ルーターの設定でUPnPは許可にしています。
どの様にしてポートの開放を確認されたのでしょうか?
それとTCP/UDPのプロトコルはあっていますか?
ルーターにアクセスして確認しました。
TCP/UDPのプロトコルがあっているかどうかとは
どういう意味でしょうか?
http://gyazo.com/3814e4ed8fe797207c8037f329e0a370.png
これがルーターにアクセスしたときの画像なのですが、
手動でポートを開放すると
「ポート変換登録情報」というところに開放されているポートが書かれているのですが
今回のアプリを実行したところ、ここに登録されることはなかったです。
Re: UPnPでポート開放
Posted: 2011年5月18日(水) 13:10
by softya(ソフト屋)
みなみ さんが書きました:ルーターにアクセスして確認しました。
ルータでは確認できないみたいなので、UPnPCと言うツールをご紹介しました。
つまり、ルータには登録されません(恒久な登録情報ではないためです)
みなみ さんが書きました:TCP/UDPのプロトコルがあっているかどうかとは
どういう意味でしょうか?
UPnPのコードですがTCPで通信するポートを開けています。
もし、通信でUDPを使っていたらポートが空いていない状態です。
なので、TCP/UDPのどちらの通信を使われているかお聞きしました。
Re: UPnPでポート開放
Posted: 2011年5月18日(水) 14:47
by Mr.D
横から失礼します。
何から何まで 同じ境遇で少し怖いのですが...
上記のソースの場合だと、
現状登録されているポート周りの判定等々が無い等の問題点が幾つか挙げられます。
※当方は、違う方法で行っているためその点も考慮して作っております。
あと上記のソースに追記で、「maps->Remove(port, proto);」を追加して閉鎖もおすすめ致します。
もう一つ、ルーターのTOP画面に「ユーティリティー機能」という文言と一緒に
「ネットワークサービスの一覧を表示」というボタンがあると思います。
そちらを押して頂くと、上記ソースを起動後であれば
|パソコン名 |IPアドレス |サービス |
|名称不明 |192.168.***.***|□□ |
|(**:**:**:**:**:**) | | |
の自分のローカルIPアドレスの右側に ファミコンのコントローラーみたいなアイコンが追加されます。
そのコントローラーが出ているIPに対しては、ポートマッピング成功です。
Re: UPnPでポート開放
Posted: 2011年5月18日(水) 15:30
by softya(ソフト屋)
Mr.D さんが書きました:横から失礼します。
何から何まで 同じ境遇で少し怖いのですが...
上記のソースの場合だと、
現状登録されているポート周りの判定等々が無い等の問題点が幾つか挙げられます。
※当方は、違う方法で行っているためその点も考慮して作っております。
あと上記のソースに追記で、「maps->Remove(port, proto);」を追加して閉鎖もおすすめ致します。
もう一つ、ルーターのTOP画面に「ユーティリティー機能」という文言と一緒に
「ネットワークサービスの一覧を表示」というボタンがあると思います。
そちらを押して頂くと、上記ソースを起動後であれば
|パソコン名 |IPアドレス |サービス |
|名称不明 |192.168.***.***|□□ |
|(**:**:**:**:**:**) | | |
の自分のローカルIPアドレスの右側に ファミコンのコントローラーみたいなアイコンが追加されます。
そのコントローラーが出ているIPに対しては、ポートマッピング成功です。
ポート判定は確かに無いですね。
それと今のコードはmaps->Remove(port, proto);を入れてしまうと単なる接続・閉鎖するだけのプログラムになってしまいますので、実際のプログラムに入れ込むときに必要なことだけを理解してください。UPnPと実際のプログラムを一体化させると思いますので。
それと家のBBR-4HGは「ネットワークサービスの一覧を表示」は古いのでないんですよね。ファームは最新なんですが。
最近のは便利なのが付いてますね。