質問: こんにちわ! windows環境で、.NetのHttpClient 、Socket で、 サーバーと通信する際に、 送信元の自分のIPアドレスを指定したいんですが、 どうしたらよいでしょうか? どういう状況かといいますと、 PCには、2枚 LANカードが刺さっており、 それぞれ別のネットワーク1、2につながっています。 サーバーA、サーバーB のIPアドレスはそれぞれ、 同一で、固定で変更することができません。 ■ネットワーク図 ``` ○サーバーA(192.168.1.2) |※ネットワーク1 LANカードA(192.168.1.5) ○PC LANカードB(192.168.1.6) |※ネットワーク2 ○サーバーB(192.168.1.2) ``` このとき、ネットワーク1,2のサーバーA,Bとそれぞれ通信をおこないたい考えです。 単純な相手先のIPアドレス指定では、 どちらか一方のサーバーとした通信ができません。 方法として、送信するLANカードを指定することができればよいみたいで、 送信したいネットワークにつながっている自分のLANカードのIPアドレスを指定すると、 そのLANカードから送信することは PINGで、送信元IPアドレス指定でできることがわかりました。 ``` ping -s 192.168.1.5 192.168.1.2 ``` だと、サーバーA 、 ``` ping -s 192.168.1.6 192.168.1.2 ``` では、サーバーBに送信することができていることがわかっています。 すいませんが、よろしくおねがいします。
回答: 本家SOでも同じような質問がありますね。 .net - Best way to specify the local endpoint for HTTP request? - Stack Overflow HttpClientでは難しいということで、HttpWebRequestクラスを使った方法が回答されています。 例えばサーバーAにアクセスするならこのようになるでしょうか。 ``` var req = HttpWebRequest.CreateHttp("http://192.168.1.2/"); req.ServicePoint.BindIPEndPointDelegate = (s, ep, retries) => new IPEndPoint(IPAddress.Parse("192.168.1.5"), 1234 + retries); var response = req.GetResponse(); ``` (以下、コメント欄での指摘を受けて追記) ServicePointは接続先(スキーマとホスト名)単位で同じものが使われます。今回の場合それらの要素は同じでしょうから、ホストAとホストBは同じServicePoint、同じBindIPEndPointDelegateが使われることになります。 このため、両方のホストにアクセスする必要があるなら、接続処理が行われるタイミング(例えばGetResponse)の時点で正しいエンドポイントを返す、具体的には「接続する直前にデリゲートを設定し、接続するまでの間に別のホストへ接続しないようにする」などの注意が必要です。 加えて、KeepAliveなどでコネクションを流用する際にもやはりホスト名で識別することになりますから、ホストAとホストBの間でコネクションが流用されないようにする必要があります。これについては `HttpWebRequest.ConnectionGroupName`.aspx) プロパティにそれぞれ違う値を設定することで可能です。