Silverlight 3.0 network 通讯

Silverlight 3.0 network 通讯,第1张

概述Silverlight 支持使用 HTTP/HTTPS (System.Net.WebClient 等) 和 Socket (System.Net.Sockets) 两种方式访问远程服务器,但基于安全原因,对这些网络访问制定了严格的安全策略。 1. HTTP/HTTPS 访问策略 (1) 始终允许同域调用。同域是指调用必须使用同一子域、协议和端口,这是出于安全原因以及防止跨域伪造。 (2) Sil

Silverlight 支持使用 http/httpS (System.Net.WebClIEnt 等) 和 Socket (System.Net.sockets) 两种方式访问远程服务器,但基于安全原因,对这些网络访问制定了严格的安全策略。

1. http/httpS 访问策略

(1) 始终允许同域调用。同域是指调用必须使用同一子域、协议和端口,这是出于安全原因以及防止跨域伪造。



(2) Silverlight 支持访问包含跨域策略文件的网站服务。跨域访问时,Silverlight Application 首先在目标 Web 服务的根路径查找 Silverlight 跨域策略文件 (clIEntaccesspolicy.xml)。如果没找到(404 Not Found)或发生其他错误,将继续在根路径处查找 Flash 跨域策略文件 (crossdomain.xml)。



clIEntaccesspolicy.xml

<?xml version="1.0" enCoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>


(3) 所有通信都是异步的。

(4) 仅支持 GET 和 POST 谓词。

(5) 支持大多数标准请求标头和所有自定义请求标头(必须是跨域策略文件中允许的标头)。

<?xml version="1.0" enCoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy >
      <allow-from http-request-headers="SOAPAction,x-custom-header">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/services/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>


(6) 只有 "200 OK" 和 "404 Not Found" 状态代码可用。

我们尝试用 WebClIEnt 访问一个跨域网站。

private voID button_Click(object sender,RoutedEventArgs e)
{
  var clIEnt = new WebClIEnt();

  clIEnt.DownloadStringCompleted += (s,ex) =>
  {
    this.TextBlock1.Text = ex.Error != null ? ex.Error.ToString() : ex.Result;
  };

  clIEnt.DownloadStringAsync(new Uri("http://localhost:8081/",UriKind.absolute));
}


当目标网站没有提供策略文件时,你会看到如下的错误信息。

@L_419_2@



在其根路径放置好 clIEntaccesspolicy.xml 后,访问正常。

2. Sockets 访问策略

创建一个供 Silverlight Application 连接的 Socket Server (非同域网站),必须符合以下安全策略。

(1) 监听 943 端口,为 Silverlight Application 提供策略文件(clIEntaccesspolicy.xml)。

(2) Socket Server 的服务端口范围必须在 4502 - 4534 之间。这是 Silverlight Application Socket 连接所允许使用的端口范围,否则连接失败。

我们写一个简单的 Time Server 作为演示。

Server CUI

class Program
{
  static voID Main(string[] args)
  {
    AccesspolicyServer();
    TimeServer();

    Console.Writeline("Press any key to exit...");
    Console.ReadKey(true);
    Environment.Exit(0);
  }

  /// <summary>
  /// 创建时间服务器线程
  /// </summary>
  private static voID TimeServer()
  {
    new Thread(() =>
    {
      // 监听 4502 端口
      var server = new TcpListener(IPAddress.Parse("127.0.0.1"),4502);
      server.Start();

      while (true)
      {
        var clIEnt = server.AcceptTcpClIEnt();
        var stream = clIEnt.GetStream();

        // 发送当前时间
        var send = EnCoding.UTF8.GetBytes(DateTime.Now.ToString());
        stream.Write(send,send.Length);

        clIEnt.Close();
      }
    }).Start();
  }

  /// <summary>
  /// 创建策略文件服务器线程
  /// </summary>
  private static voID AccesspolicyServer()
  {
    new Thread(() =>
    {
      // 监听 943 端口
      var server = new TcpListener(IPAddress.Parse("127.0.0.1"),943);
      server.Start();

      while (true)
      {
        var clIEnt = server.AcceptTcpClIEnt();
        var stream = clIEnt.GetStream();
        
        // 读取客户端发送信息,如果请求字符串不匹配则断开。
        var buffer = new Byte[1024];
        var len = stream.Read(buffer,buffer.Length);

        var rece = EnCoding.UTF8.GetString(buffer,len);
        if (String.Compare(rece,"<policy-file-request/>",true) != 0)
        {
          clIEnt.Close();
          break;
        }

        Console.Writeline(rece);

        // 发送策略文件内容
        var send = EnCoding.UTF8.GetBytes(@"
          <?xml version=""1.0"" enCoding=""utf-8""?>
          <access-policy>
            <cross-domain-access>
              <policy>
                <allow-from>
                  <domain uri=""*""/>
                </allow-from>
                <grant-to>
                  <socket-resource port=""4502-4534"" protocol=""tcp"" />
                </grant-to>
              </policy>
            </cross-domain-access>
          </access-policy>");

        stream.Write(send,send.Length);

        clIEnt.Close();
      }
    }).Start();
  }
}


ClIEnt Silverlight XAP

private voID button_Click(object sender,RoutedEventArgs e)
{
  // 创建 Socket
  var clIEnt = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

  // 创建等待句柄
  var wait = new ManualresetEvent(true);
  
  // 创建连接参数
  var args = new socketasynceventargs();
  args.RemoteEndPoint = new DnsEndPoint("127.0.0.1",4502);

  // 订阅处理事件
  args.Completed += (s,ex) =>
  {
    if (ex.Lastoperation == SocketAsyncoperation.Connect)
    {
      // 连接完成,则设置缓冲区
      var buffer = new byte[1024];
      ex.SetBuffer(buffer,buffer.Length);

      // 接收服务器数据
      clIEnt.ReceiveAsync(ex);
    }
    else if (ex.Lastoperation == SocketAsyncoperation.Receive)
    {
      // 如果接收信息正确,则显示服务器发送内容,否则显示错误信息。
      if (ex.socketError == SocketError.Success)
      {
        this.dispatcher.BeginInvoke(() =>
        {
          this.TextBlock1.Text = EnCoding.UTF8.GetString(ex.Buffer,ex.BytesTransferred);
        });
      }
      else
      {
        this.dispatcher.BeginInvoke(() =>
        {
          this.TextBlock1.Text = ex.socketError.ToString();
        });
      }

      wait.Set();
    }
  };

  // 连接服务器
  clIEnt.ConnectAsync(args);

  // 等待处理结束
  wait.WaitOne();
}


如果不启动服务器策略文件服务,或者端口不是 943,你会在客户端获得一个 AccessDenIEd 错误。



当然,如果服务器监听端口不再允许范围(4502 - 4534)内,同样也会触发这样一个错误。

【reprinted from http://www.rainsts.net/】

总结

以上是内存溢出为你收集整理的Silverlight 3.0 network 通讯全部内容,希望文章能够帮你解决Silverlight 3.0 network 通讯所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1049062.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存