![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Mar 2012
Сообщений: 7
|
Приветствую!
Пишу Delphi сервер - Flash клиент. Долго парился с файлом политик... В результате, при подключении флешки от так: ... public class Main extends MovieClip { var address: String = "127.0.0.1"; var port: int = 5000; var socket = new Socket(); public function Main() { toggle_visible_btn.addEventListener(MouseEvent.CLICK, onToggleVisible, false, 0, true); socket.addEventListener(Event.CLOSE, sockClose); socket.addEventListener(Event.CONNECT, sockConnect); socket.addEventListener(ProgressEvent.SOCKET_DATA, sockSended); socket.addEventListener(IOErrorEvent.IO_ERROR, sockIOError); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, sockSecurityError); } // private function onToggleVisible(evt: MouseEvent):void { trace("connection pressed"); //Security.loadPolicyFile(ht); socket.connect(address, port); } private function sockClose(evt: Event): void { trace("sock closed"); } private function sockConnect(evt: Event): void { trace("sock connected"); } private function sockSended(evt: ProgressEvent): void { trace("sock sended"); } private function sockIOError(evt: IOErrorEvent): void { trace("sock IO error!"); } private function sockSecurityError(evt: SecurityErrorEvent): void { trace("sock security error!"); } } ... Я её принимаю, и в ответ посылаю следующую строку: '<?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="*" to-ports="*" secure="false" /> </cross-domain-policy>' + #0; И после этого соединение у флешки сохраняется, выводится trace "sock connected". Вроде всё корошо, как бы общайся дальше данными. Но, взглянем в лог сервера: [02:49:15]: +++ Сервер запущен +++ [02:50:15]: from 127.0.0.1:51105: Соединение установлено! [02:50:15]: from 127.0.0.1:51105: принят <policy-file-request/> [02:50:15]: from 127.0.0.1:51105: Клиент закрыл соединение(закрыт сокет) [02:50:15]: from 127.0.0.1:51105: Нить остановлена [02:50:15]: from 127.0.0.1:51107: Соединение установлено! ... Т.е. флэш клиент, после того как получил файл политик, разрывает соединение и устанавливает его заново! ![]() А чуть позже я увидел пост о том, что можно держать сервер, который раздаёт только файлы политик и больше ничего, вообще отдельно от основного сервера, но как тогда посылать запрос файла политик, ведь тут я просто конектюсь к основному серверу, а флешка уже сама запрашивает у этого адреса файл политик. нужно воспользоваться Security.loadPolicyFile() ? тогда что правильно писать в скобках, т.е. как правильно писать адрес сервера для такого сокет сервера как у меня? а то примеры котоыре я видел в основном для веб севреров или ещё чего-то... Теперь идём дальше, допустим что я наладил первое подключение по вышежелаемой схеме. Теперь, какими данными общаться с основным сервером? У меня такое мнение слаживается, что общаться прийдётся строками, которые заканчиваются на нулевой байт... Т.е. я опять же видел упоминание этого на каком-то форуме, что: "флеш отправляя строку серверу, всегда в конец добавляет нулевой байт" - типа этот байт служит нам флагом для разделения пакетов на сервере. и далее: "так же и серверу необходимо отсылать строки, добавляя в конец нулевой байт" - типа флешка так тоже автоматом распознает отдельные пакеты и выдаст их в функцию обработки события ProgressEvent.SOCKET_DATA. Но во всех сетевых приложениях, которые я разрабатывал до этого, я общался следующей структурой: // определённая структура заголовка пакета TPackHeader = record PackName : TPackNameType; // числовое значение - идентификатор типа пакета PackBodySize : TPackBodyType; // 4 byte(int32) размер массива байт, который идёт сразу после заголовка пакета end; А с флешем получается только строки можно передавать чтоли? Конечно я могу адаптировать посылку и приём для строк, в этом случае разделителями пакетов будут нулевые байты, но мне бы всётаки хотелось формировать байтовые пакеты и посылать их как массивы байт, какими я и пользовался... Ещё интересует отличие типа socket и XMLSocket во флеше... в чём разница, когда тот или другой применяется или может применяться? я, например, использую: А т.к. конечная цель - это рпиложение для вконя(вконтакте), то заодно спрошу, какую строку политики надо использовать для него? Вот такую?: <?xml version="1.0"?> <cross-domain-policy> <site-control permitted-cross-domain-policies="master-only"/> <allow-http-request-headers-from domain="vk.com" headers="*"/> <allow-http-request-headers-from domain="*.vk.com" headers="*"/> <allow-http-request-headers-from domain="vkontakte.ru" headers="*"/> <allow-http-request-headers-from domain="*.vkontakte.ru" headers="*"/> <allow-access-from domain="vk.com" to-ports="80" /> <allow-access-from domain="*.vk.com" to-ports="80" /> <allow-access-from domain="vkontakte.ru" to-ports="80" /> <allow-access-from domain="*.vkontakte.ru" to-ports="80" /> </cross-domain-policy> Ах да, подскажите ещё, какую книгу взять, где бы по сокетам добротно было расписано? Очень надеюсь на помощь |
|
|||||
|
Цитата:
Цитата:
Цитата:
P.S. По ссылке выше можно найти и "Подключение к сокетам". Последний раз редактировалось bav; 22.03.2012 в 12:36. |
|
|||||
|
Регистрация: Mar 2012
Сообщений: 7
|
bav, спасибо добрый человек! понятно и спокойно прояснил некоторые детали.
Насчёт того, что отключение после съедания файла политик нормально - это я конечно понял, от этого и хотел выяснить как она поступает вообще) её логику так сказать. Если честно, то мне уже чудно то, что во флешке разработчику никак не показывается это своевольное переподключение) Хочу уточнить некоторые моменты, т.е. я могу располагать отдельный сервер для файлов политик на этом же ip(главного сервера), только на 843 порт, затем во флешке конект врубать сразу на порт главного сервака и при этом флешка сначало разберёться с файлом политик на 843-ем порту, а потом законектится без всяких запросов уже на порт главного сервака? Если так, то это чудно) Документация эта у меня уже открыта, читал, но для хорошего понимания и закрепления решил пообщаться с людьми на форуме) Ну и актуальный вопрос остаётся - это файл политик для ВКоня, как собствено его правильно писать? Правильна ли та версия, которую я написал? |
|
|||||
|
Цитата:
|
|
|||||
|
Регистрация: Mar 2012
Сообщений: 7
|
Появилась какая-то непонятная неприятность...
Соединение с серваком устанавливается нормально, срабатывает событие cliSock.addEventListener(Event.CONNECT, onSocketConnect); в его обработке следующее: private function onSocketConnect(evt: Event): void { trace("Соединение по назначенному адресу установлено"); // посылаем пакет-запрос на пингование cliSock.writeInt(2);cliSock.writeInt(1);cliSock.writeByte(0); } Далее я на кнопку сделал такую же посылку, т.е. тот же пакет. Вот обработка: private function onBtnConnectPress(evt: MouseEvent):void { trace("запрашиваем пинг"); cliSock.writeInt(2);cliSock.writeInt(1);cliSock.writeByte(0); } При этом если я в обработке подключения сделаю так: private function onSocketConnect(evt: Event): void { trace("Соединение по назначенному адресу установлено"); // посылаем пакет-запрос на пингование cliSock.writeInt(2);cliSock.writeInt(1);cliSock.writeByte(0); cliSock.writeInt(2);сliSock.writeInt(1);cliSock.writeByte(0); cliSock.writeInt(2);cliSock.writeInt(1);cliSock.writeByte(0); } |
|
|||||
|
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
А если cliSock.flush(); ? И что сниффер говорит?
Ну и на уровне сокетов вообще-то нет пакетов, это поток.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. |
|
|||||
|
Регистрация: Mar 2012
Сообщений: 7
|
Свершилось, дело было в отсутствии flush(), а точнее я его пробовал но писал его перед write методом - думал надо сначало очистить буфер, прежде чем слать что-то новое и решил что толку от него нет...
На самом деле странно, т.к. в руководстве не написано что этот метод есть команда "отправить!"... PS: опять же я поспешил в чтении руководства и не обратил внимания на понятное пояснение: "Очищает любые накопленные данные в выходном буфере сокета. В одних операционных системах метод flush() автоматически вызывается между кадрами выполнения, а в других, таких как Windows, данные никогда не отправляются, пока в коде не будет вызван метод flush(). Чтобы обеспечить надежное поведение приложения во всех операционных системах, рекомендуется вызывать метод flush() после записи каждого сообщения (или связанной группы данных) в сокет." А я прочитал только первое предложение... поспешил - насмешил вообщем. Ну конечно же мы тут все не глупые и должны были понять, что пакетом, тем более своим, я называю условный набор байт) Последний раз редактировалось TMonax; 11.04.2012 в 23:42. |
|
|||||
|
Регистрация: Nov 2009
Сообщений: 108
|
Что такое?
Пишу во флеше Security.loadPolicyFile("xmlsocket://"+serverName.text+":843"); telnetClient = new Telnet(serverName.text, int(portNumber.text), output); Со стороны флеша ошибка. Со стороны сервера тишина. package Server;
/**
*
* @author 1
*/
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Class PolicyServer
* Starts a PolicyServer on the specified port.
* Can be started as main class, passing the port number as the first command line argument
* @author Thomas Meyer, Less Rain (thomas@lessrain.com)
*
*/
public class PolicyServer extends Thread
{
/**
* Если аргумент не передается на сервер будет слушать этот порт для соединения
*/
public static final int DEFAULT_PORT = 843;
public static final String[] DEFAULT_POLICY = new String[] { "*" };
/**
* Последовательность символов, прислал Flash Player просить _policy файл
*/
public static final String POLICY_REQUEST = "<policy-file-request/>";
public static final boolean DEBUG = true;
/**
* @param args Использование первого аргумента командной строки для установки порт сервера будет слушать для соединений
*/
public static void main(String[] args)
{
int port = DEFAULT_PORT;
try
{
if (args.length>0) port = Integer.parseInt(args[0]);
}
catch (NumberFormatException e) {}
// Начало PolicyServer
(new PolicyServer( port , new String[] { "*:500" })).start();
}
/*
* переменных olicyServer класса
*/
private int _port;
private boolean _listening;
private ServerSocket _socketServer;
private String _policy;
/**
* PolicyServer constructor
* @param port_ Устанавливает порт, который прослушивает PolicyServer
*/
public PolicyServer( int port_, String[] allowedHosts_ )
{
_port = port_;
_listening=true;
if (allowedHosts_==null) allowedHosts_ = DEFAULT_POLICY;
_policy = buildPolicy(allowedHosts_);
}
private String buildPolicy( String[] allowedHosts_ )
{
StringBuffer policyBuffer = new StringBuffer();
policyBuffer.append("<?xml version=\"1.0\"?><cross-domain-policy>");
for (int i = 0; i < allowedHosts_.length; i++) {
String[] hostInfo = allowedHosts_[i].split(":");
String hostname = hostInfo[0];
String ports;
if (hostInfo.length>1) ports = hostInfo[1];
else ports = "*";
policyBuffer.append("<allow-access-from domain=\""+hostname+"\" to-ports=\""+ports+"\" />");
}
policyBuffer.append("</cross-domain-policy>");
return policyBuffer.toString();
}
/**
* Поток запуска метода, принимает входящие соединения и создает SocketConnection объектов для обработки запросов
*/
public void run()
{
try
{
_listening=true;
// Начало прослушивает соединения
_socketServer = new ServerSocket(_port,50);
if (DEBUG) System.out.println("PolicyServer listening on port "+_port);
while(_listening)
{
// Дождитесь соединения и принять его
Socket socket = _socketServer.accept();
try
{
if (DEBUG) System.out.println("PolicyServer got a connection on port "+_port);
// Начать новую тему связи
(new SocketConnection(socket)).start();
}
catch (Exception e)
{
if (DEBUG) System.out.println("Exception: "+e.getMessage());
}
try
{
// Подождите секунду, пока новое соединение будет принято, чтобы избежать затопления
sleep(1000);
}
catch (InterruptedException e) {}
}
}
catch(IOException e)
{
if (DEBUG) System.out.println("IO Exception: "+e.getMessage());
}
}
/**
* Местные SocketConnection класса
* Для каждого принятого соединения один SocketConnection создается.
* Он ждет _policy файл запроса, возвращает _policy файл и закрывает соединение сразу
* @author Thomas Meyer, Less Rain (thomas@lessrain.com)
*
*/
class SocketConnection extends Thread
{
private Socket _socket;
private BufferedReader _socketIn;
private PrintWriter _socketOut;
/**
* Конструктор принимает объект Socket для связи
* @param socket_ Socket соединения с клиентом созданные PolicyServer основной поток
*/
public SocketConnection(Socket socket_)
{
_socket = socket_;
}
/**
* Тема запуска метода ждет _policy запроса, возвращает poilcy файл и закрывает соединение
*/
public void run()
{
try
{
// инициализации сокета и читателей / писателей
_socket.setSoTimeout(10000);
_socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_socketOut =new PrintWriter(_socket.getOutputStream(), true);
}
catch (IOException e)
{
if (DEBUG) System.out.println("IO Exception "+e.getMessage());
return;
}
readPolicyRequest();
}
/**
* Подождите, и читать _policy запроса, отправленного Flash Player
* Вернуться _policy файл и закрыть соединение гнезда
*/
private void readPolicyRequest()
{
try
{
// Читайте запроса и сравнить его с запроса строку, определенную в постоянные.
// Если в надлежащем запрос _policy был отправлен выписать _policy файл
if (POLICY_REQUEST.equals(read()))
{
write(_policy);
}
}
catch (Exception e)
{
if (DEBUG) System.out.println("Exception "+e.getMessage());
}
close();
}
/**
* Читайте до нуля характер передается или максимум 100 символов
* @return The character sequence read
* @throws IOException
* @throws EOFException
* @throws InterruptedIOException
*/
private String read() throws IOException, EOFException, InterruptedIOException
{
StringBuffer buffer = new StringBuffer();
int codePoint;
boolean zeroByteRead=false;
if (DEBUG)
{
System.out.println("Reading...");
}
do
{
codePoint=_socketIn.read();
if (codePoint==0) zeroByteRead=true;
else buffer.appendCodePoint( codePoint );
}
while (!zeroByteRead && buffer.length()<100);
if (DEBUG) System.out.println("Read: "+buffer.toString());
return buffer.toString();
}
/**
*Записывает строку в клиента
* @param msg Текст для отправки клиенту (_policy файл)
*/
public void write(String msg)
{
_socketOut.println(msg+"\u0000");
_socketOut.flush();
if (DEBUG) {
System.out.println("Wrote: "+msg);
}
}
/**
* Закрытие соединения Socket все установить нулевые. Подготовлено для сбора мусора
*/
public void close()
{
try
{
if (_socket!=null) _socket.close();
if (_socketOut!=null) _socketOut.close();
if (_socketIn!=null) _socketIn.close();
System.out.println("Port close.");
}
catch (IOException e) {}
_socketIn=null;
_socketOut=null;
_socket=null;
}
}
}
|
![]() |
![]() |
Часовой пояс GMT +4, время: 23:15. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|