silverlight Socket: Unhandled Error in Silverlight Application An attempt was made to access a socket in a way forbidden by its access permissions
I basically try to reproduce the Socket example from here: http://www.silverlightshow.net/items/Sockets-and-their-implementation-in-SL2-Beta-1-including-a-chat-like-example.aspx I only made a small change in the client side, i.e.,
String safeHost = "127.0.0.1";
int port = 开发者_运维百科4509;
Then I got this permission error? Any idea why?
Unhandled Error in Silverlight Application An attempt was made to access a socket in a way forbidden by its access permissions.
I believe that the way the socket security checks work you need to use the same url string that your application uses. to make sure i am using the correct string i have always used this to construct my 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);
I have used this exact code in a similar chat application. By using the Application.Current.Host.Source.DnsSafeHost
Property you ensure that you are using the same Dns Name to access the server with the socket that the browser is using for HttpRequests.
Also are you serving the access policy file on port 943, this is another requirement of the socket support in Silverlight.
EDIT
To Confirm that you are serving the policy file you can do a number of things.
- install Fiddler, you can use it to debug all http traffic hitting your server, you should be able to see the request for the policy file.
- serve your policy file dynamically and then set a break point in your server application to confirm that it is being served. this is what i did.
here is the code i used to serve the policy file:
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();
}
}
Then to use it:
PolicyServer ps = new PolicyServer();
ps.Start();
//then when shutting down
ps.Stop();
I hosted this "server" in the same process that was running the rest of the Chat Server component. Set a breakpoint in HandleClient to confirm if it is receiving the request.
精彩评论