将Web请求绑定到特定的网络适配器

时间:2018-08-30 11:45:56

标签: c# httpwebrequest endpoint servicepointmanager servicepoint

背景

我有一个带有2个网络适配器的移动嵌入式设备(Ubuntu / Mono)。一个是WiFi,另一个是GSM。要求是,当WiFi适配器连接到Internet(在预定AP范围内)时,应用程序会通过WiFi上传数据( HTTPS POST ),但是当WiFi不可用但GSM可用时,它通过GSM链接上传数据。

测试

为了实现这一点,我创建了一个基于云的Web服务,如果您向其发出HTTP GET,它会返回OK。想法是让一个线程定期发出绑定到特定适配器的GET请求并检查结果。 OK(确定)的结果表示适配器已连接到Internet,而超时通常表示未连接。然后,我可以使用它来确定用于请求的适配器。

我创建了一个小型测试应用程序,该应用程序启动了一个线程,该线程发出绑定到特定适配器的GET请求。我使用request.BindIPEndPointDelegate将请求绑定到适配器。当我在WiFi适配器上运行该应用程序时,结果与预期的一样。当WiFi AP开启时,请求返回OK;当AP关闭时,请求超时。在GSM适配器上运行该应用程序时也是如此。

但是,当我更新该应用程序以启动2个线程(其中一个用于WiFi适配器和GSM适配器)时,会出现问题。当AP开启时,WiFi和GSM请求顺利进行。当我关闭AP时,WiFi请求最初会超时,但过一会儿会返回成功的结果,这是错误的。因为两个线程的URI都相同,所以我怀疑ServicePointManager会将相同的ServicePoint返回到两个线程,并且某种程度上由于多线程而返回了麻烦。

下一个测试是创建2个不同的端点。每个WiFi和GSM请求一个,希望ServicePointManager总是返回不同的ServicePoint。不幸的是,这没有任何积极影响。

我将不胜感激。

代码如下:

  private HttpWebRequest CreateRequest(Uri webApiUri,IPAddress adapterAddress)
  {
   IPEndPoint endPoint = new IPEndPoint(adapterAddress, 0);

   HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(webApiUri);

   webRequest.ServicePoint.BindIPEndPointDelegate =
      delegate(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
      {
         if (retryCount == 1)
          throw new WebException(string.Format("Cannot bind to adapter {0}", endPoint));

        return endPoint;
      };

    return webRequest;
  }

0 个答案:

没有答案