Я считаю, что для проверки безопасности сокетов необходимо использовать ту же строку 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 для доступа к серверу с сокетом, который браузер использует для запросов HttpRequest.
Также вы предоставляете файл политики доступа на порт 943, это еще одно требование поддержки сокетов в Silverlight.
EDIT
Чтобы подтвердить, что вы обслуживаете файл политики, вы можете сделать несколько вещей.
- установить Fiddler , вы можете использовать его для отладки всего http-трафика, попадающего на ваш сервер, вы должны увидеть запрос файла политики.
- обслуживает файл политики динамически, а затем устанавливает точку останова в приложении сервера, чтобы подтвердить, что он обслуживается. это то, что я сделал.
вот код, который я использовал для обслуживания файла политики:
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();
Я разместил этот «сервер» в том же процессе, в котором выполнялась остальная часть компонента Чат-сервер. Установите точку останова в HandleClient, чтобы подтвердить, получает ли он запрос.