Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Серверные технологии и Flash (http://www.flasher.ru/forum/forumdisplay.php?f=62)
-   -   Обработка сокетов (http://www.flasher.ru/forum/showthread.php?t=188086)

client510 28.11.2012 19:02

Обработка сокетов
 
Всем, здравствуйте.
Долго мучился, но все таки (не без вышей помощи) сделал авторизацию на своем чате.
Теперь новая проблема:
Нужно чтобы при входе в чат, логин передавался серверу путем сокета и использовался в качестве имени при общение.
Соединение установил и вроде все должно работать, но при компиляции в области вывода выходят эти ошибки:
Код:

Error #2044: Необработанный ioError:. text=Error #2031: Ошибка сокета.
        at avfc_1_0_fla::enter_user_118/frame1()
        at flash.display::MovieClip/gotoAndStop()
        at avfc_1_0_fla::MainTimeline/fl_MouseClickHandler_3()
Error #2044: Необработанный securityError:. text=Error #2048: Нарушение изолированной среды: file:///E|/WebServers2/home/videochat/www/avfc%5F1%5F0.swf не может загрузить данные из :8080.
        at avfc_1_0_fla::enter_user_118/frame1()
        at flash.display::MovieClip/gotoAndStop()
        at avfc_1_0_fla::MainTimeline/fl_MouseClickHandler_3()

Я первый раз имею дело с сокетами.
Подскажите пожалуйста, что это за ошибки и как исправить?
Заранее благодарен!

bav 28.11.2012 21:36

1.
Цитата:

Соединение установил
Чем это подтверждается? Вам удалось передать с клиента на сервер и обратно какие-нибудь данные?
2. Работает ли секьюрити-сервер на 843 порту, раздающий политики безопасности?
3. Не закрыт ли сокет на клиенте при попытке обращения к нему?

client510 28.11.2012 23:40

Вот полный результат вывода:
Код:

Успех!
NetConnection.Connect.Success
undefined
Не верный логин или пароль.
Error #2044: Необработанный ioError:. text=Error #2031: Ошибка сокета.
        at avfc_1_0_fla::enter_user_118/frame1()
        at flash.display::MovieClip/gotoAndStop()
        at avfc_1_0_fla::MainTimeline/fl_MouseClickHandler_3()
У нас уже: 5 пользователей
Error #2044: Необработанный securityError:. text=Error #2048: Нарушение изолированной среды: file:///E|/WebServers2/home/videochat/www/avfc%5F1%5F0.swf не может загрузить данные из :8080.
        at avfc_1_0_fla::enter_user_118/frame1()
        at flash.display::MovieClip/gotoAndStop()
        at avfc_1_0_fla::MainTimeline/fl_MouseClickHandler_3()

Вот код джава:
Код:

import java.io.*;
import java.net.*;
 
class SimpleServer
{
    private static SimpleServer server;
    ServerSocket socket;
    Socket incoming;
    BufferedReader readerIn;
    PrintStream printOut;
 
    public static void main(String[] args)
    {
        int port = 8080;
 
        try
        {
            port = Integer.parseInt(args[0]);
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
            // Catch exception and keep going.
        }
 
        server = new SimpleServer(port);
    }
 
    private SimpleServer(int port)
    {
        System.out.println(">> Starting SimpleServer");
        try
        {
            socket = new ServerSocket(port);
            incoming = socket.accept();
            readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
            printOut = new PrintStream(incoming.getOutputStream());
            printOut.println("Enter EXIT to exit.\r");
            out("Enter EXIT to exit.\r");
            boolean done = false;
            while (!done)
            {
                String str = readerIn.readLine();
                if (str == null)
                {
                    done = true;
                }
                else
                {
                    out("Echo: " + str + (char)0));
                    if(str.trim().equals("EXIT"))
                    {
                        done = true;
                    }
                }
                incoming.close();
            }
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }
 
    private void out(String str)
    {
        printOut.println(str);
        System.out.println(str);
    }
}

И вот кусок кода, который отвечает за сокеты:
Код AS3:

if(paswords == pasword[l])
                                {
                                        socket.connect(null,8080);
                                        socket.send("test \n");
                                        socket.addEventListener(ProgressEvent.SOCKET_DATA, onConnectSend);
 
                                        if(true)
                                        {
                                                trace("Успех!");
                                                MovieClip(this.root).gotoAndStop(1, "Монтажный кадр 6");
                                        }

Заранее извините если код топорный, это первое мое приложение на флеш.

bav 29.11.2012 00:09

Во-первых давайте разберемся, вы используете класс Socket или XMLSocket? Во-вторых, у вас сервер запущен локально (localhost)? В-третьих, сокеты - штука асинхронная. То есть нельзя после вызова функции socket.connect(...) тут же пытаться слать какие-нибудь данные (socket.send("test \n")). Сначала нужно дождаться события, извещающего вас о том, что подключение произошло (Event.CONNECT). Ответьте на первые два вопроса, а то из кода мало что понятно.

client510 29.11.2012 00:31

Я использую XMLSocket. Сервер запущен в localhost. Пробовал
Цитата:

В-третьих, сокеты - штука асинхронная. То есть нельзя после вызова функции socket.connect(...) тут же пытаться слать какие-нибудь данные (socket.send("test \n")). Сначала нужно дождаться события, извещающего вас о том, что подключение произошло (Event.CONNECT).
.
Результат нолевой!
Изначально код был такой:
Код AS3:

if(paswords == pasword[l])
                                {
                                        socket.connect(null,8080);
                                        socket.addEventListener(Event.CONNECT, onConnects);
 
                                        if(true)
                                        {
                                        socket.send("test \n");
                                        socket.addEventListener(ProgressEvent.SOCKET_DATA, onConnectSend);
                                                MovieClip(this.root).gotoAndStop(1, "Монтажный кадр 6");
                                        }

Добавлено через 4 минуты
Большое спасибо за ссылки, но я их уже почти выучил на изучь.

Добавлено через 10 минут
Ошибка может быть в том, что я не могу разобраться, где размещать файл политики.

Добавлено через 14 часов 6 минут
Так, одно проблема решена! Теперь я уже точно знаю, что сервер принимает сообщение, но не оправляет.
Причина тоже ясна, не добавляется нолевой бфйт. Попытка прописать добавление в коде, Компилятор меняет на свое или выдает ошибку, при ручном редактирование. Подскажите как быть?

Добавлено через 15 часов 41 минуту
Всем спасибо. Разобрался сам. тема закрыта.

bav 29.11.2012 19:03

Напишите, если не лень и для будущих поколений, в чем была ошибка и как вы ее решили.

client510 30.11.2012 17:29

Я прошу прощение у всех, но оказывается рано радовался!! После того, как я повесил обработчики событий и правильно прописал вывод, обнаружил, что не в чем я не разобрался! А ошибки как были так и остались. Вот эти две ошибки:
Код:

#1034: Ошибка типа Coercion: невозможно преобразовать flash.events::IOErrorEvent@2ea93469 в flash.errors.IOError.
и
Код:

[SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: Нарушение изолированной среды: file:///E|/WebServers2/home/videochat/www/avfc%5F1%5F0.swf не может загрузить данные из :2525."]
. Со вчерашнего вечера ломаю голову как их исправить. Если сможет помочь, буду очень благодарен!

КорДум 01.12.2012 08:23

При первой передаче данных на сервер флеш плеер создает еще один сокет на 843 порту (по умолчанию) и отсылает по нему серверу строку "<policy-file-request/>". Строка эта всегда одной длины, так что на сервере можно читать одинаковое количество байтов. В ответ флеш плеер хочет получить файл политики безопасности — тоже строку — в котором будет описано, может ли клиент подключаться к серверу. И если нет или же в ответ ничего не приходит, то:
Цитата:

[SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: Нарушение изолированной среды: file:///E|/WebServers2/home/videochat/www/avfc%5F1%5F0.swf не может загрузить данные из :2525."]
Отсылайте с сервера в ответ
Код AS3:

<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>

И обязательно завершите нулевым байтом.

Добавлено через 6 минут
Ну и по сокетам и байтам будет полезно.

client510 04.12.2012 16:59

Уже десять дней топчусь во круг сщкетов. Не ни кто не может помочь? Я перепробовал все выше предлагаемые варианты, но эффекта - 0.
Вот все мои коды:
Сервер
Код:

import java.net.*;
import java.io.*;

class SimpleServer
{
    public static void main(String[] args)
    {
        try
        {
            System.out.println("-> Security server started...");
            ServerSocket server = new ServerSocket(2525);
            Socket client;
            DataOutputStream out;
            DataInputStream in;
           
            // Reading crossdomain.xml
            FileInputStream xmlFile = new FileInputStream("crossdomain.xml");
            int xmlBytesCount = xmlFile.available();
           
            byte[] xmlBytes = new byte[xmlBytesCount + 1];
            xmlFile.read(xmlBytes, 0, xmlBytesCount);
            xmlBytes[xmlBytesCount] = 0;
            xmlFile.close();
           
            byte[] policyRequest = new byte[23];
           
//            for (;;)
//          {
                client = server.accept();
                out = new DataOutputStream(client.getOutputStream());
                in = new DataInputStream(client.getInputStream());
               
                in.read(policyRequest, 0, 23);
               
                out.write(xmlBytes, 0, xmlBytesCount + 1);
                out.flush();
                System.out.println(":: FSS :: Policy sended to " + client.toString());
                client.close();
//        }
               
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
       
        int port = 4444; // случайный порт (может быть любое число от 1025 до 65535)
        SimpleServer(port);
     
    }
    static ServerSocket socket;
    static Socket incoming;
    static BufferedReader readerIn;
    static PrintStream printOut;
 
    private static void SimpleServer(int port)
    {
        System.out.println(">> Starting SimpleServer");
        try
        {
            socket = new ServerSocket(port);
            incoming = socket.accept();
            readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
            printOut = new PrintStream(incoming.getOutputStream());
            out("Enter EXIT to exit.\r");
            boolean done = false;
            while (!done)
            {
                String str = readerIn.readLine();
                if (str == null)
                {
                    done = true;
                }
                else
                {
                    out("Echo: " + str + (char)0);
                    if(str.trim().equals("EXIT"))
                    {
                        done = true;
                    }
                }
               
            }
            incoming.close();
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }
 
    private static void out(String str)
    {
            System.out.println(str);
        printOut.println(str);
        printOut.flush();
       
    }
}

Файл политики:
Код:

i<?xml version="1.0"?>
<!-- http://www.foo.com/crossdomain.xml -->
<cross-domain-policy>
      <allow-access-from domain="127.0.0.1" to-ports="4444" />
</cross-domain-policy>

И флеш:
Код AS3:

import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.net.XMLSocket;
import flash.text.TextField;
 
stop();
 
var userloader:URLLoader = new URLLoader();
var userrequest:URLRequest = new URLRequest("user.xml");
    userloader.load(userrequest);
        userrequest.data;
        userloader.addEventListener(Event.COMPLETE, onUserLoad);
var xml:XML = new XML;
var userLogin:XMLList;
var userPaswurd:XMLList;
var username:Array = new Array();
var pasword:Array = new Array();
var i:int;
var j:int;
 
function onUserLoad(e:Event):void
{
        xml = XML(e.target.data);
        userLogin = xml..user_login.text();
        userPaswurd = xml..user_password.text();
        for(i = 0; i < userLogin.length(); i++)
        {
                username.push(userLogin[i]);
        }
        for(j = 0; j < userPaswurd.length(); j++)
        {
                pasword.push(userPaswurd[j]);
        }
}
 
var configloader:URLLoader = new URLLoader();
var configrequest:URLRequest = new URLRequest("configuration.xml");
    configloader.load(configrequest);
        configloader.addEventListener(Event.COMPLETE, onSocketConfig);
var socketconfig:XML;
var sockethost:XMLList;
var socketport:XMLList;
 
function onSocketConfig(e:Event):void
{
        socketconfig = XML (e.target.data);
        sockethost = socketconfig..socket_host.text();
        socketport = socketconfig..socket_port.text();
}
var ports:Number = 4444;
var xmlsocket:XMLSocket = new XMLSocket("127.0.0.1", ports);
var textFields:TextField = new TextField();
        xmlsocket.addEventListener(Event.CLOSE, closeSocket);
        xmlsocket.addEventListener(Event.CONNECT, connectSocket);
        xmlsocket.addEventListener(DataEvent.DATA, dataSocket);
        xmlsocket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorSocket);
        xmlsocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorSocket);
 
enter_page.addEventListener(MouseEvent.CLICK, onEnter);
 
function onEnter(e:MouseEvent):void
{
        var logins:String = logins.text;
        var paswords:String = paswords.text;
        var categories:String = categories.text;
        var k:int;
        var l:int;
 
        if(logins == "" || paswords == "")
        {
                trace(enter_status.text = ("Ошибка! Не заполнены поля"));
                return;
        }
 
        for(k = 0; k < username.length; k++)
        {
                if(logins == username[k])
                {
                        for(l = 0; l < pasword.length; l++)
                {
                                if(paswords == pasword[l])
                                {
                                        xmlsocket.connect("127.0.0.1", 2525);
                        try
                        {
                                Security.loadPolicyFile("xmlsocket://127.0.0.1:2525");
                        }
                        catch(e:Error)
                        {
                                textFields.appendText("\n Нет файла политики! \n");
                        }
                        xmlsocket.connect("127.0.0.1",ports);
                                        if(true)
                                        {
                                          MovieClip(this.root).gotoAndStop(1, "Монтажный кадр 6");
                                        }
                                }
                }
                }
        }
        if(logins != username[k] || paswords != pasword[l])
        {
                trace(enter_status.text = ("Не верный логин или пароль."));
                return;
        }
}
function closeSocket(event:Event):void
{
        trace("\ncloseHandler: \n" + event);
}
function connectSocket(event:Event):void
{
        trace("\nconnectHandler: \n" + event);
        xmlsocket.send("test\n");
        trace("data sending...\n");
}
function dataSocket(event:DataEvent):void
{
    trace("\ndataHandler: \n" + event);
}
function ioErrorSocket(event:IOErrorEvent):void
{
        trace("\nioErrorHandler: \n" + event);
}
function securityErrorSocket(event:SecurityErrorEvent):void
{
        trace("\nsecurityErrorHandler: \n" + event);
}
 
reminder.addEventListener(MouseEvent.CLICK, onreminder);
 
function onreminder(e:MouseEvent):void
{
        gotoAndStop(2);
}

А это вывод:
Код:

ioErrorHandler:
[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2031: Ошибка сокета. URL: 127.0.0.1"]

securityErrorHandler:
[SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: Нарушение изолированной среды: file:///E|/WebServers2/home/videochat/www/avfc%5F1%5F0.swf не может загрузить данные из 127.0.0.1:4444."]

Кто может помогите разобраться пожалуйста!

maxkar 04.12.2012 22:56

Вам уже советовали сделать сервер на порту 843, этого порта я в коде не нашел. Далее. Где-то в мейне (в кадре, что ли?) вы коннектитесь к порту 4444 (запрос полиси придет на 843). А ваш сервер слушает на 2525 первого запроса. Очевидно, на 4444 никто не ответит. Затем в onEnter вы коннектитесь на порт 2525 (при этом запрос на полиси опят придет на 843, если отказ не будет закэширован). И только после этого вы загружаете policy file. Вот эта попытка может быть даже проиходт успешно. Только не факт, что ваш полиси-файл разрешит соединяться с другим портом (в asdoc по Security и в разделе Security справки оно может быть по-разному трактовано). Ваш трейс, вероятно, из кадра еще выводится (номеров строк и названий методов нет).

Кроме того, я не уверен в корректности вашей java-части. Во-первых, вы можете не до конца читать ваш файл политики. Более того, вы вполне можете прочитать 0 байт. Это укладывается в контракт available! Читайте документацию на этот метод. Во-вторых, вы можеет вычитать запрос policy-file-request не полностью, но это в данном случае не важно (да и маловероятно). В третьих. Не out.flush(), socket.close(); Правильно socket.shutdown(); socket.close(). Иначе что-то отправленное может не дойти. Не поддерживают внутри себя сокеты flush, особенность у них такая.

client510 05.12.2012 12:37

Снова переписал все заново. Прописал 843 порт. Как и раньше, эффект нолевой! Что делать дальше?

Добавлено через 4 часа 17 минут
Алло-о-о! Есть кто-то из супер спецов на этом форуме? На протяжение шести часов, еще раз, прочитал кучу статей, а эту почти выучили на из уч, просмотрел десяток видео, Перепробовал все ваши советы - результата 0! Может проблема в сервере? Ребята, у кого-то есть рабочий сервер? Выложите пожалуйста код. Я брал здесь и тут, но не на одном не работает.

Добавлено через 5 часов 2 минуты
Кстати, ни одна из этих команд :
Цитата:

Чтобы запустить сервер XMLSocket, откройте командную строку и введите java SimpleServer. Файл SimpleServer.class может находиться в любом месте на локальном или сетевом компьютере. Его не обязательно сохранять в корневом каталоге веб-сервера.

Если сервер запустить не удается из-за того, что файлы находятся не в пути к классам Java, попробуйте запустить сервер с помощью java -classpath . SimpleServer.
на моем компьютере не выполняются.

maxkar 06.12.2012 01:26

А с какой ошибкой ваша команда не выполняется? Может, там javac нужно запустить. Или доступа к портам нет.

Вообще, я не понимаю, откуда у кучи народа (не только у вас) возникают проблемы с сокет-серверами. Если разбираться в технологии и все делать строго по спеке, никаких проблем нет.

Код:

import java.io.*;
import java.net.*;

public class SS {
        private static final String POLICY_FILE_RESPONCE =
                "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>";
        public static void main(String [] args) throws Exception {
                final ServerSocket ss = new ServerSocket(3128);
                while (true) {
                        final Socket s = ss.accept();
                        new Thread(new Runnable() {
                                @Override
                                public void run() {
                                        handles(s);
                                }
                        }).start();
                }
        }

        static void handles(Socket s) {
                System.out.println("Client!");
                try {
                        final InputStream is = new BufferedInputStream(s.getInputStream());
                        final OutputStream os = s.getOutputStream();
                        boolean first = true;
                        boolean die = false;
                        do {
                                final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                                int readed;
                                while ((readed = is.read()) > 0)  {
                                        buffer.write(readed);
                                }
                                final byte[] bytes = buffer.toByteArray();
                                final String dummyContent = new String(bytes, "UTF-8");
                                System.out.println(dummyContent);
                                if ("<policy-file-request/>".equals(dummyContent) && first) {
                                        os.write(POLICY_FILE_RESPONCE.getBytes("UTF-8"));
                                        os.write(0);
                                        die = true;
                                }
                                first = false;
                                if (readed == -1)
                                        die = true;
                                if ("<quit/>".equals(dummyContent)) {
                                        die = true;
                                }
                                os.write(bytes);
                                os.write(0);
                        } while (!die);
                        s.shutdownOutput();
                        s.close();
                        System.out.println("Good buy, cruel world!");
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

Код AS3:

package {
import flash.display.*;
import flash.text.*;
import flash.geom.*;
import flash.net.*;
import flash.events.*;
import flash.system.*;
public class Test extends Sprite {
  const tf : TextField = new TextField();
  var sock : XMLSocket;
  public function Test() {
        Security.loadPolicyFile("xmlsocket://127.0.0.1:3128");
        sock = new XMLSocket("127.0.0.1", 3128);
        sock.addEventListener(Event.CONNECT, connected);
        sock.addEventListener(DataEvent.DATA, receive);
        addChild(tf);
  }
 
  private function connected(e : Event) : void {
    tf.text = "COnnected";
        sock.send(<test/>);
  }
 
  private function receive(e : DataEvent) : void {
          tf.text = e.data.toString();
        sock.send(<quit/>);
  }
}
}

Вот. Рабочее. Проверялось. Импорты в as от другого теста остались. Импорты со * потому, что писалось все в vim'е а не в IDE. Если и оно у вас не заработает, по шагам пишите, что именно вы делали и какие ошибки на каких шагах выдавались.

Обработка исключений не совсем правильная (для примера - пойдет, в production close нужно в finally делать). Запись в два приема (нулевой байт отдельно) тоже может быть не очень для production (учитывая, что у вас вообще не работает - без разницы).

client510 06.12.2012 01:41

Пробавал по разному, но ошибка одна и та же:
Цитата:

ioErrorHandler:
[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2031: Ошибка сокета. URL: 127.0.0.1"]

securityErrorHandler:
[SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: Нарушение изолированной среды: file:///E|/WebServers2/home/videochat/www/avfc%5F1%5F0.swf не может загрузить данные из 127.0.0.1:4444."]
Спасибо за пример, буду пробовать.


Часовой пояс GMT +4, время: 12:36.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.