Silverlight WCF netTcpBinding问题

发布于 2024-09-01 23:21:11 字数 1179 浏览 6 评论 0原文

尝试通过 Silverlight 使用 netTcpBinding 调用 WCF,我收到错误:

“TCP 错误代码 10013:尝试以访问权限禁止的方式访问套接字。这可能是由于尝试访问如果服务未配置为跨域访问,则您可能需要联系服务的所有者以通过 HTTP 公开套接字跨域策略,并在允许的套接字端口范围 4502 中托管该服务。 -4534。”

我的 WCF 服务托管在 IIS7 中,绑定到:

端口 80 上的 http://localhost.myserivce.com 和端口 4502 上的 net.tcp

我可以看到 http://localhost.myserivce.com/myservice.svc< /a> 如果我浏览到它(我的主机文件将该域指向本地主机)。 我还可以看到 http://localhost.myserivce.com/clientaccesspolicy.xml

<?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="4502-4534" protocol="tcp" />
         </grant-to>
      </policy>
   </cross-domain-access>
</access-policy>

我是什么我做错了吗?

Trying to call a WCF with a netTcpBinding via Silverlight, I am getting the error:

"TCP error code 10013: An attempt was made to access a socket in a way forbidden by its access permissions.. This could be due to attempting to access a service in a cross-domain way while the service is not configured for cross-domain access. You may need to contact the owner of the service to expose a sockets cross-domain policy over HTTP and host the service in the allowed sockets port range 4502-4534."

My WCF service is hosted in IIS7, bound to:

http://localhost.myserivce.com on port 80
and net.tcp on port 4502

I can see http://localhost.myserivce.com/myservice.svc if I browse to it (my hosts file is pointing this domain to localhost).
I can also see http://localhost.myserivce.com/clientaccesspolicy.xml:

<?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="4502-4534" protocol="tcp" />
         </grant-to>
      </policy>
   </cross-domain-access>
</access-policy>

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

洋洋洒洒 2024-09-08 23:21:11

从 SL4 RTM 开始,这一情况已发生变化。 SL4 net.tcp 客户端不会在 tcp 943 上查找客户端访问策略,而是使用使用 Web 服务器根端口 80 的旧方法。奇怪的是,这在任何地方都没有详细记录,但我可以确认这是发布时的行为。

最重要的是,从 SL4 RTM 开始,您描述的方法应该有效,而此处的其他答案则无效。

This has changed as of SL4 RTM. A SL4 net.tcp client will not look for the client access policy on tcp 943, but will instead use the old method of using the root of the webserver, port 80. Oddly, this isn't really well documented anywhere, but I can confirm that this is the behavior as of the release.

Bottom line, as of SL4 RTM, the method you describe should work and the other answer here does not.

末蓝 2024-09-08 23:21:11

如果您尝试在端口范围 4502-4534 中建立 TCP 连接,Silverlight 将首先在端口 943 上发布请求以检索客户端访问策略文件内容 - 它不会读取 http://localhost.myserivce.com/clientaccesspolicy.xml,因为这仅适用于 HTTP 请求。
您需要将服务器配置为侦听 TCP 端口 943,期望请求字符串等于 并回复 xml 文件内容。

下面的代码显示了一个基本实现,您需要使用端口 943 向其传递本地 IPEndPoint:

public class SocketPolicyServer
{
    private const string m_policyRequestString = "<policy-file-request/>";
    private string m_policyResponseString;
    private TcpListener m_listener;
    bool _started = false;

    public SocketPolicyServer()
    {
        m_policyResponseString = File.ReadAllText("path/to/clientaccesspolicy.xml");
    }

    public void Start(IPEndPoint endpoint)
    {
        m_listener = new TcpListener(endpoint);
        m_listener.Start();
        _started = true;
        m_listener.BeginAcceptTcpClient(HandleClient, null);
    }

    public event EventHandler ClientConnected;
    public event EventHandler ClientDisconnected;

    private void HandleClient(IAsyncResult res)
    {
        if(_started)
        {
            try
            {
                TcpClient client = m_listener.EndAcceptTcpClient(res);
                m_listener.BeginAcceptTcpClient(HandleClient, null);
                this.ProcessClient(client);
            }
            catch(Exception ex)
            {
                Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
            }
        }
    }

    public void Stop()
    {
        _started = false;
        m_listener.Stop();
    }

    public void ProcessClient(TcpClient client)
    {
        try
        {
            if(this.ClientConnected != null)
                this.ClientConnected(this, EventArgs.Empty);

            StreamReader reader = new StreamReader(client.GetStream(), Encoding.UTF8);
            char[] buffer = new char[m_policyRequestString.Length];
            int read = reader.Read(buffer, 0, buffer.Length);

            if(read == buffer.Length)
            {
                string request = new string(buffer);

                if(StringComparer.InvariantCultureIgnoreCase.Compare(request, m_policyRequestString) == 0)
                {
                    StreamWriter writer = new StreamWriter(client.GetStream());
                    writer.Write(m_policyResponseString);
                    writer.Flush();
                }
            }
        }
        catch(Exception ex)
        {
            Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
        }
        finally
        {
            client.GetStream().Close();
            client.Close();
            if(this.ClientDisconnected != null)
                this.ClientDisconnected(this, EventArgs.Empty);
        }
    }
}

If you try to establish a TCP connection in port range 4502-4534, Silverlight will first post a request on port 943 to retrieve the client access policy file content - It won't read the file at http://localhost.myserivce.com/clientaccesspolicy.xml, because this is only for HTTP requests.
You need to configure your server to listen on TCP port 943, expect a request string equal to <policy-file-request/> and reply with the xml file content.

The code below shows a basic implementation, you need to pass it a local IPEndPoint using port 943:

public class SocketPolicyServer
{
    private const string m_policyRequestString = "<policy-file-request/>";
    private string m_policyResponseString;
    private TcpListener m_listener;
    bool _started = false;

    public SocketPolicyServer()
    {
        m_policyResponseString = File.ReadAllText("path/to/clientaccesspolicy.xml");
    }

    public void Start(IPEndPoint endpoint)
    {
        m_listener = new TcpListener(endpoint);
        m_listener.Start();
        _started = true;
        m_listener.BeginAcceptTcpClient(HandleClient, null);
    }

    public event EventHandler ClientConnected;
    public event EventHandler ClientDisconnected;

    private void HandleClient(IAsyncResult res)
    {
        if(_started)
        {
            try
            {
                TcpClient client = m_listener.EndAcceptTcpClient(res);
                m_listener.BeginAcceptTcpClient(HandleClient, null);
                this.ProcessClient(client);
            }
            catch(Exception ex)
            {
                Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
            }
        }
    }

    public void Stop()
    {
        _started = false;
        m_listener.Stop();
    }

    public void ProcessClient(TcpClient client)
    {
        try
        {
            if(this.ClientConnected != null)
                this.ClientConnected(this, EventArgs.Empty);

            StreamReader reader = new StreamReader(client.GetStream(), Encoding.UTF8);
            char[] buffer = new char[m_policyRequestString.Length];
            int read = reader.Read(buffer, 0, buffer.Length);

            if(read == buffer.Length)
            {
                string request = new string(buffer);

                if(StringComparer.InvariantCultureIgnoreCase.Compare(request, m_policyRequestString) == 0)
                {
                    StreamWriter writer = new StreamWriter(client.GetStream());
                    writer.Write(m_policyResponseString);
                    writer.Flush();
                }
            }
        }
        catch(Exception ex)
        {
            Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
        }
        finally
        {
            client.GetStream().Close();
            client.Close();
            if(this.ClientDisconnected != null)
                this.ClientDisconnected(this, EventArgs.Empty);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文