我基本上尝试从这里重现Socket示例:http://www.silverlightshow.net/items/Sockets-and-their-implementation-in-SL2-Beta-1-including-a-chat-like-example.aspx 我只在客户端做了一点改动,即
String safeHost = "127.0.0.1";
int port = 4509;
然后我收到了这个权限错误?知道为什么吗?
Silverlight应用程序中的未处理错误尝试以其访问权限禁止的方式访问套接字。
答案 0 :(得分:3)
我相信套接字安全检查的工作方式,您需要使用应用程序使用的相同url字符串。为了确保我使用正确的字符串我一直用它来构建我的DNSEndPoint:
int Port = 4509;
DnsEndPoint ep = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, Port, AddressFamily.InterNetwork);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.NoDelay = true;
SocketAsyncEventArgs ea = new SocketAsyncEventArgs{RemoteEndPoint = ep};
//set up completed event handler et al.
sock.ConnectAsync(ea);
我在类似的聊天应用程序中使用了这个确切的代码。通过使用Application.Current.Host.Source.DnsSafeHost
属性,您可以确保使用相同的Dns名称来访问具有浏览器用于HttpRequests的套接字的服务器。
您还在端口943上提供访问策略文件,这是Silverlight中套接字支持的另一个要求。
修改
要确认您正在为策略文件提供服务,您可以执行许多操作。
这是我用来提供策略文件的代码:
public abstract class Server
{
protected Socket Listener { get; set; }
protected int Port { get; private set; }
protected int Backlog { get; private set; }
protected bool isStopped { get; set; }
protected SocketAsyncEventArgs AcceptArgs {get;set;}
public Server(int port)
{
AcceptArgs = new SocketAsyncEventArgs();
AcceptArgs.Completed += new EventHandler<SocketAsyncEventArgs>(Accept_Completed);
isStopped = true;
Port = port;
Backlog = 100;
}
public Server(int port, int backlog)
{
isStopped = true;
Port = port;
Backlog = backlog;
}
public void Start()
{
isStopped = false;
Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ep = new IPEndPoint(IPAddress.Any, Port);
Listener.ExclusiveAddressUse = true;
Listener.Bind(ep);
//Console.WriteLine("Listening on " + Port);
Listener.Listen(Backlog);
Listener.AcceptAsync(AcceptArgs);
}
void Accept_Completed(object sender, SocketAsyncEventArgs e)
{
if (isStopped) return;
Socket client = e.AcceptSocket;
//Console.WriteLine("Accepted Connection From: " + client.RemoteEndPoint.ToString());
e.AcceptSocket = null;
Listener.AcceptAsync(AcceptArgs);
HandleClient(client);
}
public virtual void Stop()
{
if (isStopped) throw new InvalidOperationException("Server already Stopped!");
isStopped = true;
try
{
Listener.Shutdown(SocketShutdown.Both);
Listener.Close();
}
catch (Exception)
{
}
}
protected abstract void HandleClient(Socket Client);
}
public class PolicyServer : Server
{
public const String policyStr = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri=""*"" />
</allow-from>
<grant-to>
<socket-resource port=""4530"" protocol=""tcp"" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>";
private byte[] policy = Encoding.ASCII.GetBytes(policyStr);
private static string policyRequestString = "<policy-file-request/>";
public PolicyServer(): base(943)
{
}
protected override void HandleClient(Socket socket)
{
TcpClient client = new TcpClient { Client = socket };
Stream s = client.GetStream();
byte[] buffer = new byte[policyRequestString.Length];
client.ReceiveTimeout = 5000;
s.Read(buffer, 0, buffer.Length);//read in the request string, but don't do anything with it
//you could confirm that it is equal to the policyRequestString
s.Write(policy, 0, policy.Length);
s.Flush();
socket.Shutdown(SocketShutdown.Both);
socket.Close(1);
client.Close();
}
}
然后使用它:
PolicyServer ps = new PolicyServer();
ps.Start();
//then when shutting down
ps.Stop();
我在运行Chat Server组件其余部分的同一进程中托管了这个“服务器”。在HandleClient中设置断点以确认它是否正在接收请求。