Silverlight 支持使用 HTTP/HTTPS (System.Net.WebClient 等) 和 Socket (System.Net.Sockets) 两种方式访问远程服务器,但基于安全原因,对这些网络访问制定了严格的安全策略。
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

Code
<?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) 支持大多数标准请求标头和所有自定义请求标头(必须是跨域策略文件中允许的标头)。

Code
<?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 访问一个跨域网站。

Code
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));
}
当目标网站没有提供策略文件时,你会看到错误信息。
在其根路径放置好 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

Code
1
class Program
2

{
3
static void Main(string[] args)
4
{
5
AccessPolicyServer();
6
TimeServer();
7
8
Console.WriteLine("Press any key to exit
");
9
Console.ReadKey(true);
10
Environment.Exit(0);
11
}
12
13
/**//// <summary>
14
/// 创建时间服务器线程
15
/// </summary>
16
private static void TimeServer()
17
{
18
new Thread(() =>
19
{
20
// 监听 4502 端口
21
var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 4502);
22
server.Start();
23
24
while (true)
25
{
26
var client = server.AcceptTcpClient();
27
var stream = client.GetStream();
28
29
// 发送当前时间
30
var send = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
31
stream.Write(send, 0, send.Length);
32
33
client.Close();
34
}
35
}).Start();
36
}
37
38
/**//// <summary>
39
/// 创建策略文件服务器线程
40
/// </summary>
41
private static void AccessPolicyServer()
42
{
43
new Thread(() =>
44
{
45
// 监听 943 端口
46
var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 943);
47
server.Start();
48
49
while (true)
50
{
51
var client = server.AcceptTcpClient();
52
var stream = client.GetStream();
53
54
// 读取客户端发送信息,如果请求字符串不匹配则断开。
55
var buffer = new Byte[1024];
56
var len = stream.Read(buffer, 0, buffer.Length);
57
58
var rece = Encoding.UTF8.GetString(buffer, 0, len);
59
if (String.Compare(rece, "<policy-file-request/>", true) != 0)
60
{
61
client.Close();
62
break;
63
}
64
65
Console.WriteLine(rece);
66
67
// 发送策略文件内容
68
var send = Encoding.UTF8.GetBytes(@"
69
<?xml version=""1.0"" encoding=""utf-8""?>
70
<access-policy>
71
<cross-domain-access>
72
<policy>
73
<allow-from>
74
<domain uri=""*""/>
75
</allow-from>
76
<grant-to>
77
<socket-resource port=""4502-4534"" protocol=""tcp"" />
78
</grant-to>
79
</policy>
80
</cross-domain-access>
81
</access-policy>");
82
83
stream.Write(send, 0, send.Length);
84
85
client.Close();
86
}
87
}).Start();
88
}
89
}
90
91
Client Silverlight XAP
92
93
private void Button_Click(object sender, RoutedEventArgs e)
94

{
95
// 创建 Socket
96
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
97
98
// 创建等待句柄
99
var wait = new ManualResetEvent(true);
100
101
// 创建连接参数
102
var args = new SocketAsyncEventArgs();
103
args.RemoteEndPoint = new DnsEndPoint("127.0.0.1", 4502);
104
105
// 订阅处理事件
106
args.Completed += (s, ex) =>
107
{
108
if (ex.LastOperation == SocketAsyncOperation.Connect)
109
{
110
// 连接完成,则设置缓冲区
111
var buffer = new byte[1024];
112
ex.SetBuffer(buffer, 0, buffer.Length);
113
114
// 接收服务器数据
115
client.ReceiveAsync(ex);
116
}
117
else if (ex.LastOperation == SocketAsyncOperation.Receive)
118
{
119
// 如果接收信息正确,则显示服务器发送内容,否则显示错误信息。
120
if (ex.SocketError == SocketError.Success)
121
{
122
this.Dispatcher.BeginInvoke(() =>
123
{
124
this.TextBlock1.Text = Encoding.UTF8.GetString(ex.Buffer, 0, ex.BytesTransferred);
125
});
126
}
127
else
128
{
129
this.Dispatcher.BeginInvoke(() =>
130
{
131
this.TextBlock1.Text = ex.SocketError.ToString();
132
});
133
}
134
135
wait.Set();
136
}
137
};
138
139
// 连接服务器
140
client.ConnectAsync(args);
141
142
// 等待处理结束
143
wait.WaitOne();
144
}
145
如果不启动服务器策略文件服务,或者端口不是 943,你会在客户端获得一个 AccessDenied 错误。
当然,如果服务器监听端口不再允许范围(4502 - 4534)内,同样也会触发这样一个错误。
本文来自CSDN博客http://blog.csdn.net/zjfei/archive/2009/07/27/4384368.aspx
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步