Файловый сервер политики сокетов C # для низкоуровневых подключений к сокетам AS3.0?

StackOverflow https://stackoverflow.com/questions/1409771

Вопрос

Как мне создать файловый сервер политики сокетов на C #.Все, что ему нужно сделать, это прослушать на порту 843 строку "<policy-file-request />", за которой следует нулевой байт, а затем вернуть XML-строку (которая является файлом политики сокетов).

Я раньше не кодировал подобные вещи и не уверен, с чего начать.Создаю ли я его в службе Windows?Любые советы или ссылки приветствуются.

Предыстория:

Чтобы связаться с веб-службой из flash, я использую библиотеку 'as3httpclient' вместо URLRequest /URLLoader.Это потому, что это дает мне возможность отправлять пользовательские заголовки с запросами GET.Эта библиотека использует низкоуровневые сокеты для выполнения своих функций.

Когда flash использует низкоуровневые сокеты для подключения к серверу, он ищет файл политики сокетов - и он должен обслуживаться файловым сервером политики сокетов.

Статья о файле политики сокетов от Adobe

Это было полезно?

Решение

Несколько вещей, о которых следует знать, используя предложенную вами архитектуру:

Попытка отправить 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);

и способ получения:

    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 выглядит так, как будто его не помешало бы доработать, но этого должно быть достаточно, чтобы вы начали.

Другие советы

Создайте прослушивающий сокет.

Когда соединение открыто, выполните прием и дождитесь ожидаемой строки.При получении отправьте содержимое файла, а затем закройте сокет.

Оберните это в службу (работающую от имени учетной записи с низкими привилегиями).

Большая часть работы выполняется с помощью Система.Сеть.Розетки.Розетка класс, документация содержит образец, API очень похож на BSD socket API в целом (в основном существует сопоставление 1: 1 из BSD API в метод Socket (или help type)), поэтому любой фон должен быть легко переводимым.

Мне пришлось решать эту задачу как с Java, так и с C #, они очень похожи.

Вы можете взглянуть на файл политики java.

Некоторую проблему можно увидеть в этом ответе: https://stackoverflow.com/a/12854204/1343667

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top