• Silverlight Working with Sockets


    Silverlight和服务端进行通信前会向服务端请求一个安全策略文件,在Silverlight 3.0中这个请求端口为943、Silverlight 4.0也可以是80。请求的模式取决于你的应用程序中SocketAsyncEventArgs.SocketClientAccessPolicyProtocol所指的值为Http或Tcp。如果是Http,需要在IIS中为80的站点添加net.tcp类型的绑定,并指明端口(4502 - 4530)。Tcp则需要一个应用程序负责监听943端口,当请求为时返回你的策略文件内容。策略文件的格式可以如下:

    <?xml version="1.0" encoding="utf-8"?>
    <access-policy>
      <cross-domain-access>
        <policy>
          <allow-from http-request-headers="*">
            <domain uri="*" />
          </allow-from>
          <grant-to>
        <socket-resource port="4530" protocol="tcp" />
          </grant-to>
        </policy>
      </cross-domain-access>
    </access-policy>

    详细的内容可以参考Network Security Access Restrictions in Silverlight这篇文章:

    http://msdn.microsoft.com/en-us/library/cc645032(v=VS.95).aspx

    如果你编写的服务端需要和Silverlight进行Tcp通信,请准备一个策略服务端监听943端口。当Silverlight应用创建和服务端连接时,它会先请求你的PolicyServer并获取允许使用的端口。

    关于WCF NET.TCP请参考WCF NET.TCP Protocol in Silverlight这篇文章:

    http://www.silverlightshow.net/items/WCF-NET.TCP-Protocol-in-Silverlight-4.aspx

      1 using System;
      2 using System.IO;
      3 using System.Net;
      4 using System.Net.Sockets;
      5 using System.Text;
      6 using System.Threading;
      7 
      8 namespace SLPolicyServer
      9 {
     10     class Program
     11     {
     12         /// <summary>
     13         /// 主程序入口
     14         /// </summary>
     15         /// <param name="args">参数</param>
     16         static void Main(String[] args)
     17         {
     18             String policyFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "clientaccesspolicy.xml");
     19 
     20             if (args.Length == 1)
     21             {
     22                 policyFile = args[0];
     23 
     24                 Console.WriteLine(args[0]);
     25             }
     26 
     27             new Thread(() =>
     28             {
     29                 new PolicyServer(policyFile);
     30                 Thread.Sleep(Timeout.Infinite);
     31             }).Start();
     32 
     33             Console.ReadKey();
     34         }
     35     }
     36 
     37     /// <summary>
     38     /// 策略连接
     39     /// </summary>
     40     class PolicyConnection
     41     {
     42         /// <summary>
     43         /// 策略请求字符串
     44         /// </summary>
     45         private static readonly String PolicyRequestString = "<policy-file-request/>";
     46 
     47         private Socket m_connection;
     48         private Byte[] m_buffer;
     49         private Byte[] m_policy;
     50         private Int32 m_received;
     51 
     52         /// <summary>
     53         /// 构造函数
     54         /// </summary>
     55         /// <param name="client">客户端套接字</param>
     56         /// <param name="policy">策略数据</param>
     57         public PolicyConnection(Socket client, Byte[] policy)
     58         {
     59             m_connection = client;
     60             m_policy = policy;
     61             m_buffer = new Byte[PolicyRequestString.Length];
     62             m_received = 0;
     63 
     64             try
     65             {
     66                 m_connection.BeginReceive(m_buffer, 0, PolicyRequestString.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
     67             }
     68             catch (SocketException)
     69             {
     70                 m_connection.Close();
     71             }
     72         }
     73 
     74         /// <summary>
     75         /// 接收数据
     76         /// </summary>
     77         /// <param name="ar">异步结果</param>
     78         private void OnReceive(IAsyncResult ar)
     79         {
     80             try
     81             {
     82                 m_received += m_connection.EndReceive(ar);
     83 
     84                 // 发送字符不足则继续接收
     85                 if (m_received < PolicyRequestString.Length)
     86                 {
     87                     m_connection.BeginReceive(m_buffer, m_received, PolicyRequestString.Length - m_received, SocketFlags.None, new AsyncCallback(OnReceive), null);
     88 
     89                     return;
     90                 }
     91 
     92                 String request = Encoding.UTF8.GetString(m_buffer, 0, m_received);
     93 
     94                 if (StringComparer.InvariantCultureIgnoreCase.Compare(request, PolicyRequestString) != 0)
     95                 {
     96                     m_connection.Close();
     97 
     98                     return;
     99                 }
    100 
    101                 // 发送策略文件
    102                 m_connection.BeginSend(m_policy, 0, m_policy.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
    103             }
    104             catch (SocketException)
    105             {
    106                 m_connection.Close();
    107             }
    108         }
    109 
    110         /// <summary>
    111         /// 发送数据
    112         /// </summary>
    113         /// <param name="ar">异步结果</param>
    114         private void OnSend(IAsyncResult ar)
    115         {
    116             try
    117             {
    118                 m_connection.EndSend(ar);
    119             }
    120             finally
    121             {
    122                 m_connection.Close();
    123             }
    124         }
    125     }
    126 
    127     /// <summary>
    128     /// 策略服务
    129     /// </summary>
    130     class PolicyServer
    131     {
    132         private Socket m_listener;
    133         private Byte[] m_policy;
    134 
    135         /// <summary>
    136         /// 构造函数
    137         /// </summary>
    138         /// <param name="policyFile">策略文件</param>
    139         public PolicyServer(String policyFile)
    140         {
    141             // 读取策略文件
    142             FileStream policyStream = new FileStream(policyFile, FileMode.Open);
    143             m_policy = new byte[policyStream.Length];
    144 
    145             policyStream.Read(m_policy, 0, m_policy.Length);
    146             policyStream.Close();
    147 
    148             // 监听943端口
    149             m_listener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
    150             m_listener.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0);
    151             m_listener.Bind(new IPEndPoint(IPAddress.IPv6Any, 943));
    152             m_listener.Listen(10);
    153             m_listener.BeginAccept(new AsyncCallback(OnConnection), null);
    154         }
    155 
    156         /// <summary>
    157         /// 关闭
    158         /// </summary>
    159         public void Close()
    160         {
    161             m_listener.Close();
    162         }
    163 
    164         /// <summary>
    165         /// 连接
    166         /// </summary>
    167         /// <param name="ar">异步结果</param>
    168         private void OnConnection(IAsyncResult ar)
    169         {
    170             Socket client = null;
    171 
    172             try
    173             {
    174                 client = m_listener.EndAccept(ar);
    175             }
    176             catch (SocketException)
    177             {
    178                 return;
    179             }
    180 
    181             // 建立策略连接
    182             PolicyConnection pc = new PolicyConnection(client, m_policy);
    183 
    184             m_listener.BeginAccept(new AsyncCallback(OnConnection), null);
    185         }
    186     }
    187 }
  • 相关阅读:
    d3js selections深入理解
    d3js scales深入理解
    d3js shape深入理解
    如何使用chrome devtool调试Mobile网页?
    为什么有时父元素无法包含子元素?
    base64编码以及url safe base64是怎么工作的?
    古老的CSS同高列问题
    springboot2.0整合redis的发布和订阅
    如何在centos7中设置redis服务器开机自启动
    1.Linux安装redis
  • 原文地址:https://www.cnblogs.com/junchu25/p/2633517.html
Copyright © 2020-2023  润新知