自宅のコンピューターからオフィスのコンピューターへの TCP 接続を確立する必要があります。
オフィスには、複数のコンピューターが接続されているルーターがあります。そのルーターにはインターネットがあるため、そのルーターに接続されているすべてのコンピューターにもインターネットがあります。私の家には、インターネットにアクセスできるコンピューターがあります。オフィスのコンピューターがサーバーとして機能し、自宅のコンピューターがサーバーに接続する必要があります。以前は、サーバー上のポート転送トラフィックによって次のように接続できました。
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
upnpnat = new NATUPNPLib.UPnPNATClass();
mappings = upnpnat.StaticPortMappingCollection;
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.150.146", true, "plsease work");
// this code tels the router to forward all tcp traffic comming from port
// 1300 to the server computer (it's lan ip address happens to be 192.168.150.146)
//...
自宅から接続できました。(簡単な方法は、オフィスのルーターのポートを開き、それらを自分のコンピューターに転送することです。問題は、オフィスのルーターにアクセスできないことです)
現在、彼らは私のオフィスのルーターを新しいルーターに交換しましたが、コードを使用できません。新しいルーターを使用して、前のコードを実行すると、次のようになります。
マッピングは null を返すことに注意してください。したがって、マッピングを追加できません。
オフィスの一部の人々は、たとえばライムワイヤーやビットトレントを使用しているため、接続を確立する方法があるはずです。私の問題はおそらく許可に関係していると思いますか?どうすればこれを解決できますか?
編集
調査の結果、私がやろうとしているのは「ファイアウォールへのUDPパンチホール」であることがわかりました。私は実際にtcp接続でそれをやりたいです。tcp と upd の puch holing の違いが何であるかわかりません.... つまり、クライアントがルーターで構成を行うことなくナシを見つけることができるようにすることです。
.
.
.
.
.
.
アップデート
わかりましたので、皆さんがこの質問に投稿したことをc#で試してみたと思います:わかりました、私がしたことをお見せしましょう:
これから説明する内容を理解するには、この図を参照する必要があるかもしれません。
ご存知のように、コンピューター A とコンピューター B の間に tcp 接続を確立したいと考えています。これを行う方法は、tcp パンチホールと呼ばれるものを使用することです。
ステップ 1: 最初に、サーバー S で新しい接続のリッスンを開始します。
TcpListener server = new TcpListener(System.Net.IPAddress.Parse(“192.168.11.109”), 55550);
Server.Start();
var client = server.AcceptSocket(); \\ wait here until someone connects
ステップ 2: 次のようにコンピューター A を使用してサーバーに接続します。
TcpClient tcpClient = new TcpClient("192.168.11.109", 55550);
ステップ 3: コンピューター A でステップ 2 のコードを実行した後、サーバー S のデバッグは次のようになります。
ステップ 4: ここでの目標は、コンピューター B からコンピューター A に接続することです。サーバー S には、接続を確立するために B が必要とする情報があります。実際には、コンピューター B とサーバー S の間に接続を確立して、B が A に接続するためにサーバー S が B に適切なパラメーターを与えることができるようにする必要があります。
ステップ 5: デバッグ中なのでパラメーターを確認できるので、ポート 3313 でリッスンしてコンピューター A をサーバーにします。すべてのパッケージがルーターに送信されるため、コンピューター A がそのポート (3313) でリッスンするようにします。ポート 3313 の X をコンピューター A に送信する必要があります。
\\ COMPUTER A
TcpListener server = new TcpListener(System.Net.IPAddress.Parse("192.168.0.120"), 3313);
server.Start();
var newClient = server.AcceptSocket(); \\ wait here until a client gets connected
ステップ 6: これで、コンピューター A はポート 3313 で新しい接続をリッスンするようになります。ポート 3313 は重要です。これは、ルーター x がそのポートから受信したすべてのパッケージをコンピューター A に転送する必要があるためです。
コンピュータ A は新しい接続を待っています。
ステップ 7: それでは早速!コンピューター B からの接続を確立したいと考えています。実際にはサーバー S がパラメーターを渡しますが、これを機能させようとしているだけなので、コンピューター B でプログラムをすばやく作成します。
TcpClient tcpClient = new TcpClient(“192.168.11.108”, 3313);
\\192.168.11.108 is the address of router X
ついに:
何らかの理由で、コンピューター B がコンピューター A に接続できません。
接続できない理由は、ルーター X がパッケージをコンピューター A に転送しなかったためです (ルーター X のポート 54540 でポート転送を有効にしており、そのポートを使用すると機能するため、これを知っています)。ルーター X がポート 3313 からのトラフィックをコンピューター A に転送しなかった理由がわかりません。コンピューター A は既にサーバー S への接続を確立しており、サーバー S がポート 3313 を介してルーター X に送信したすべてのものがコンピューター A に送信されました。ポート 3313 を介してルーター X にパッケージを送信すると、コンピューター A によって受信されない!?
PS:
ここで示したものはすべて、実際には 3 つのルーター X、Y、Z があり、サーバー S、コンピューター A、コンピューター B もあることに注意してください。