用于低级 AS3.0 套接字连接的 C# 套接字策略文件服务器?

发布于 2024-08-04 15:45:28 字数 523 浏览 3 评论 0原文

如何用 C# 制作套接字策略文件服务器。它所要做的就是在端口 843 上侦听字符串“”后面跟一个 NULL 字节,然后返回一个 XML 字符串(这是套接字策略文件)。

我以前没有编写过此类代码,并且不确定从哪里开始。我是在 Windows 服务中创建它吗?欢迎任何提示或链接。

背景:

为了从 Flash 联系 Web 服务,我使用“as3httpclient”库而不是 URLRequest/URLLoader。这是因为它使我能够使用 GET 请求发送自定义标头。该库使用低级套接字来完成其工作。

当闪存使用低级套接字连接到服务器时,它会查找套接字策略文件 - 这需要由套接字策略文件服务器提供服务。

Adobe 的套接字策略文件文章

How do I go about making a socket policy file server in C#. All it has to do is listen on port 843 for the string "<policy-file-request/>" followed by a NULL byte and then return an XML string (which is the socket policy file).

I haven't coded this sort of thing before and am unsure of where to start. Do I create it in a windows service? Any tips or links are welcome.

Background:

To contact a web service from flash I am using the 'as3httpclient' library instead of the URLRequest/URLLoader. This is because it gives me the ability to send custom headers with GET requests. This library uses low-level sockets to do its stuff.

When flash uses low-level sockets to connect to a server it looks for a socket policy file - and this needs to be served up by a socket policy file server.

Socket Policy File Article from Adobe

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

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

发布评论

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

评论(3

近箐 2024-08-11 15:45:28

使用建议的架构时需要注意的一些事项:

尝试发送通过套接字进行 HTTP 请求

原则上,您需要注意,即使您可以使用套接字在较低级别上进行 http 聊天,但在很多情况下,这种方式的通信都会失败。如果用户在浏览器中启用了代理服务器,则主要会发生这些失败,因为在通过套接字连接时没有有效的方法来发现并随后使用代理。

为了创建策略服务器,您可以使用 TcpListener 类。您将开始监听,如下所示:

var tcpListener = new TcpListener(IPAddress.Any, 843 );
tcpListener.start();
tcpListener.BeginAcceptTcpClient(new AsyncCallback(NewClientHandler), null);

NewClientHandler 方法将具有以下形式:

    private void NewClientHandler(IAsyncResult ar)
    {
        TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar);
        ...

此时您可能希望将 tcpClient 对象提供给您自己创建的类,以处理来自套接字的数据的验证。我将其称为 RemoteClient。

在 RemoteClient 中,您将有类似这样的内容:

    var buffer=new byte[BUFFER_SIZE];
    tcpClient.GetStream().BeginRead(buffer, 0, buffer.Length, Receive, null);

和一个 Receive 方法:

    private void Receive(IAsyncResult ar)
    {
        int bytesRead;
        try
        {
            bytesRead = tcpClient.GetStream().EndRead(ar);
        }
        catch (Exception e)
        {

            //something bad happened. Cleanup required
            return;
        }

        if (bytesRead != 0)
        {
            char[] charBuffer = utf8Encoding.GetChars(buffer, 0, bytesRead);
            try
            {
                tcpClient.GetStream().BeginRead(buffer, 0, buffer.Length, Receive, null);
            }
            catch (Exception e)
            {
                //something bad happened. Cleanup required
            }
        }
        else
        {
            //socket closed, I think?
            return;
        }
    }

和一些发送方法:

    public void Send(XmlDocument doc)
    {
        Send(doc.OuterXml);
    }
    private void Send(String str)
    {

        Byte[] sendBuf = utf8Encoding.GetBytes(str);
        Send(sendBuf);
    }
    private void Send(Byte[] sendBuf)
    {
        try
        {
            tcpClient.GetStream().Write(sendBuf, 0, sendBuf.Length);
            tcpClient.GetStream().WriteByte(0);
            tcpClient.GetStream().WriteByte(13); //very important to terminate XmlSocket data in this way, otherwise Flash can't read it.

        }
        catch (Exception e)
        {
            //something bad happened. cleanup?
            return;
        }
    }

我认为这就是所有重要的细节。我前段时间写过这个... Receive 方法看起来可以重新设计,但它应该足以让您开始。

A few things to be aware of using your suggested architecture:

Trying to send an HTTP request over sockets

Principally, you need to be aware that even though you can chat http at a lower level using sockets, there are a large number of cases where communication in this fashion will fail. Mainly these failures will occur if the user has a proxy server enabled in their browser, as there is no effective means of discovering and subsequently using the proxy when connecting via a socket.

In order to make a policy server, you can use the TcpListener class. You would start listening as follows:

var tcpListener = new TcpListener(IPAddress.Any, 843 );
tcpListener.start();
tcpListener.BeginAcceptTcpClient(new AsyncCallback(NewClientHandler), null);

The method NewClientHandler would have the form:

    private void NewClientHandler(IAsyncResult ar)
    {
        TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar);
        ...

At which point you might want to supply the tcpClient object to a class of your own creation to handle the validation of the data coming from the socket. I'm going to call it RemoteClient.

In RemoteClient, you'd have something like this:

    var buffer=new byte[BUFFER_SIZE];
    tcpClient.GetStream().BeginRead(buffer, 0, buffer.Length, Receive, null);

and a Receive method:

    private void Receive(IAsyncResult ar)
    {
        int bytesRead;
        try
        {
            bytesRead = tcpClient.GetStream().EndRead(ar);
        }
        catch (Exception e)
        {

            //something bad happened. Cleanup required
            return;
        }

        if (bytesRead != 0)
        {
            char[] charBuffer = utf8Encoding.GetChars(buffer, 0, bytesRead);
            try
            {
                tcpClient.GetStream().BeginRead(buffer, 0, buffer.Length, Receive, null);
            }
            catch (Exception e)
            {
                //something bad happened. Cleanup required
            }
        }
        else
        {
            //socket closed, I think?
            return;
        }
    }

and some send methods:

    public void Send(XmlDocument doc)
    {
        Send(doc.OuterXml);
    }
    private void Send(String str)
    {

        Byte[] sendBuf = utf8Encoding.GetBytes(str);
        Send(sendBuf);
    }
    private void Send(Byte[] sendBuf)
    {
        try
        {
            tcpClient.GetStream().Write(sendBuf, 0, sendBuf.Length);
            tcpClient.GetStream().WriteByte(0);
            tcpClient.GetStream().WriteByte(13); //very important to terminate XmlSocket data in this way, otherwise Flash can't read it.

        }
        catch (Exception e)
        {
            //something bad happened. cleanup?
            return;
        }
    }

That's all the important details I think. I wrote this some time ago... the Receive method looks like it could do with a rework, but it should be enough to get you started.

梦里泪两行 2024-08-11 15:45:28

创建监听套接字。

当连接打开时,执行接收并等待预期的字符串。收到后发送文件内容,然后关闭套接字。

将其包装在服务中(作为低权限帐户运行)。

大部分工作都是通过 System.Net.Sockets.Socket 类,文档包含一个示例,该 API 总体上与 BSD 套接字 API 非常相似(很大程度上有从 BSD API 到 Socket(或帮助类型)方法的 1:1 映射),因此任何背景都应该很容易翻译。

Create a listening socket.

When a connection is opened, perform a receive and wait for the expected string. When received send the file content and then close the socket.

Wrap this in a service (running as a low privilege account).

Most of the work is done with the System.Net.Sockets.Socket class, the documentation contains a sample, The API is very similar to the BSD socket API overall (largely there is a 1:1 mapping from BSD API to Socket (or help type) method) so any background should be easily translatable.

凯凯我们等你回来 2024-08-11 15:45:28

我必须使用 Java 和 C# 来完成这项任务,它们非常相似。

您可以查看 java 策略文件

一些问题可以在这个答案中看到:https://stackoverflow.com/a/12854204/1343667

I had to to this task with both Java and C#, they are quite similar.

You can have a look at java policy file.

Some issue can see at this answer: https://stackoverflow.com/a/12854204/1343667

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文