Тема: Socket
Показать сообщение отдельно
Старый 20.07.2010, 19:59
nbid вне форума Посмотреть профиль Отправить личное сообщение для nbid Найти все сообщения от nbid
  № 6  
Ответить с цитированием
nbid

Регистрация: Oct 2009
Сообщений: 5
Attention Такая же проблема...

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

Вот флеш код:
Код:
package Lib
{
	import flash.display.Sprite;
	import flash.events.ProgressEvent;
	import flash.net.Socket;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.utils.ByteArray;
	import flash.system.Security;

	public class SocketConnect extends Sprite
	{
  // Константы состояний для описания протокола
  public const VERSION:int = 0;
  public const AUTH:int = 1;
  public const WORKING:int = 2;
  
  // Сопоставляем состояние и функцию обработки
  private var stateMap:Object;
  
  // Отслеживаем текущее состояние протокола
  private var currentState:int;

  private var socket:Socket;
  private var field:TextField;

  public function SocketConnect()
  {
  	field = new TextField();
  	field.border = true;
  	field.borderColor = 0xFF00FF;
  	field.width = 600;
  	field.height = 400;
  	field.type = TextFieldType.DYNAMIC;
  	addChild(field);

  	field.appendText(' * Задача: Авторизироваться на сервере. * \n');
  	
  	// Сопоставляем состояния и константы состояний
  	stateMap = new Object();
  	stateMap[VERSION] = version;
  	stateMap[AUTH] = auth;
  	stateMap[WORKING] = working;
  	
  	// Инициализируем текущее состояние
  	currentState = VERSION;

  	try
  	{
    socket = new Socket();
    socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
    socket.connect('localhost', 843);
    field.appendText('Log: Соединение с сервером. \n');
  	}
  	catch(e:SecurityError)
  	{
    field.appendText('Error: '+e+'.\n');
  	}
  }

  private function onSocketData(event:ProgressEvent):void
  {
  	field.appendText('Socket: Поступили данные состояния номер: "'+currentState+'".\n');
  	
  	// Ищем функцию обработки исходя из текущего состояния
  	var processFunc:Function = stateMap[currentState];
  	processFunc();
  }
  
  private function version():void
  {
  	field.appendText('Log: Читаем версию с сервера\n');
  	
  	// Шаг 1 - читаем версию с сервера
  	var version:int = socket.readInt();

  	field.appendText('Chat: Версия: '+version+'\n');
  	
  	// Следующее состояние: Авторизация
  	currentState = AUTH;
  	
  	field.appendText('Log: Запрашиваем авторизацию на сервере\n');
  	
  	// Шаг 2 - возвращаем версию на сервер
  	socket.writeUTFBytes('auth|Nexus:xxxaaa');
  	socket.flush();
  }
  
  // Авторизация
  private function auth():void
  {
  	field.appendText('Log: Читаем результат авторизации\n');

  	var string:String = socket.readUTFBytes(socket.bytesAvailable);
  	
  	if(string)
    field.appendText('Chat: Авторизация прошла успешно\n');
  	else
    field.appendText('Chat: В авторизации отказано\n');
  	
  	// Следующее состояние: Начало работы
  	currentState = WORKING;
  	
  	field.appendText('Log: Запрашиваем данные\n');

  	socket.writeUTFBytes('getData');
  	socket.flush();
  }
  
  // Начало работы
  private function working():void
  {
  	field.appendText('Log: Получаем данные\n');

  	var string:String = socket.readUTFBytes(socket.bytesAvailable);
  	
  	field.appendText('Chat: '+string+'\n');

  	// Завершаем работу сокета
  	socket.close();
  	
  	field.appendText(' * Задача выполнена, сокет закрыт. * \n');
  }
	}
}
Вот PHP сервер (комменты будут глупо выглядеть т.к. переводил через гугл транслейт:

Код:
#!/usr/local/bin/php
<?php
// Порт подключения
$port = 843;
$ip = '78.46.98.68';

// Создаёт конечную точку соединения (сокет) и возвращает ресурс сокета
// Тип подключения TCP/IP
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// Опции сокета:
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); // Отсчеты либо локальные адреса могут быть использованы повторно

// Связать адрес и порт с сокетом
socket_bind($socket, 0, $port);

// Начать прослушивать соединение на сокете
socket_listen($socket);
	
// Создать список всех клиентов, которые будут связаны с нами
// Добавить сокет к этому списку
$clients = array($socket);

while(true)
{
	sleep(1); // Задержка
	
	// создать копию что бы $clients не получила изменения socket_select()
	$read = $clients;
   
	// Получить список всех клиентов, которые имеют данные, которые будут читать
	// Если нет клиентов с данными, перейти к следующей итерации
	
	// Принимает массивы сокетов и ожидает их для изменения статуса
	if(socket_select($read, $write = NULL, $except = NULL, 0) < 1) continue;
   
	// Проверить, есть ли клиент, пытающийся установить соединение
	if(in_array($socket, $read))
	{
  // Принять клиента, и добавить его в массив $clients
  $clients[] = $newsock = socket_accept($socket);

  // Отправить клиенту приветствие
  socket_write($newsock, "Привет клиент! Ты приконнектился к серверу;)\nСейчас онлайн ".(count($clients) - 1)." клиентов\n");
  //socket_write($newsock, "Hello\n");

  // Запросить удалённую сторону данного сокета, чтобы получить пару host/port
  socket_getpeername($newsock, $client_ip);
  
  // Написать в SSH оповещение
  echo "New client connected: {$client_ip}\n";
    
  // Удалить сокет от клиентов с массива данных
  unset($read[array_search($socket, $read)]);
	}

	// Цикл по всем клиентам, которые имеют данные для чтения
	foreach($read as $read_sock)
	{
  // Читать новую строку или до 1024 байтов
  $data = @socket_read($read_sock, 1024, PHP_BINARY_READ);
    
  // Если клиент отключился
  if($data === false)
  {
  	// Удалить клиента из массива $clients
  	unset($clients[array_search($read_sock, $clients)]);
  	
  	// Написать в SSH оповещение
  	echo "client disconnected.\n";
  	
  	// Переход к следующему клиенту
  	continue;
  }

  // Очистить пробелы по краям
  $data = trim($data);
  echo $data."\n";

  if($data == '<policy-file-request/>')
  {

  	$return = "<?xml version=\"1.0\"?>"
      ."<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">"
      ."<cross-domain-policy>"
      ."<allow-access-from domain=\"*\" secure=\"true\" to-ports=\"*\" />"
      ."</cross-domain-policy>\n";

      /*
  	$sreturn =
       '<'.'?xml version="1.0" encoding="UTF-8"?'.'>'.
       '<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd">'.
           '<allow-access-from domain="*" to-ports="*" secure="false" />'.
           '<site-control permitted-cross-domain-policies="master-only" />'.
       '</cross-domain-policy>'; 
  	*/
  	
  	foreach($clients as $send_sock)
  	{
    @socket_write($send_sock, $return);
  	}
  	
  	echo "Police file sended...\n";
  	
  	continue;
  }

  // Проверить, есть ли данные после обрезки от пространства
  if(!empty($data))
  {
  	$data = explode('|',$data);
  	$command = $data[0];
  	$text = $data[1];
  	
  	// Команды
  	$return = '';
  	switch($command)
  	{
    case 'auth': $return = 'Запрос авторизации'; break;
    case 'getData': $return = 'Различные данные из базы данных'; break;
    default: $return = 'Нет запроса'; break;
  	}

  	// Оповестить о входящих данных
  	echo "Data accept ".iconv('utf-8', 'cp866', $command.' - '.$return)."\n";
  	//echo "Data accept ".$command." - ".$return."\n";
  	
  	// Послать данные для всех клиентов в массиве $clients, за исключением первого, чей сокет
  	foreach($clients as $send_sock)
  	{
    // Если это тот чей сокет - перейти к следующему
    #if($send_sock == $socket || $send_sock == $read_sock) continue;
      
    // Написать сообщение для клиента и добавить символ новой строки в конец сообщения
    @socket_write($send_sock,"{$return}");
  	}
     
  }
    
	}
}

// Закрыть сокет
socket_close($socket);
?>
Если запускаю из Abobe Flash CS4 то получаю следующее:
Цитата:
* Задача: Авторизироваться на сервере. *
Log: Соединение с сервером.
Socket: Поступили данные состояния номер: "0".
Log: Читаем версию с сервера
Chat: Версия: -794832512
Log: Запрашиваем авторизацию на сервере
Socket: Поступили данные состояния номер: "1".
Log: Читаем результат авторизации
Chat: Авторизация прошла успешно
Log: Запрашиваем данные
Socket: Поступили данные состояния номер: "2".
Log: Получаем данные
Chat: Различные данные из базы данных
* Задача выполнена, сокет закрыт. *
А в шелле:
Цитата:
New client connected: 127.0.0.1
auth|Nexus:xxxaaa
Data accept auth - Запрос авторизации
getData
Data accept getData - Различные данные из базы данных
А если запускаю отдельно, то получаю следующее (не работает):
Цитата:
* Задача: Авторизироваться на сервере. *
Log: Соединение с сервером.
А в шелле:
Цитата:
New client connected: 127.0.0.1
<policy-file-request/>
Police file sended...
client disconnected.
client disconnected.
(два диссконекта наверно из-за того что предыдущий еще не дисконнектился.

Local Playback security стоит - Access network only

А если ставлю Access local files only
то когда запускаю из флеша - все также, а когда запускаю отдельно, то флешка показывает этот текст:

Цитата:
* Задача: Авторизироваться на сервере. *
Error: SecurityError: Error #2010.
и Шелл при этом вообще нечего не выводит.

Если будете помогать и отвечать, скажите что в "Local Playback security" должно стоять, если РНР сервер и сама флешка будет лежать на одном и том же сервере.

Так вот, в чем моя проблема? Объясните пожалуйста Я больше не могу с этим жить!
очень благодарю тех кто решит помочь