示例#1
0
 function server_loop()
 {
     while (true) {
         $read_fds = $this->fds;
         $write = $exp = null;
         if (stream_select($read_fds, $write, $exp, null)) {
             foreach ($read_fds as $socket) {
                 $socket_id = (int) $socket;
                 if ($socket_id == $this->server_socket_id) {
                     if ($client_socket_id = parent::accept()) {
                         $this->fds[$client_socket_id] = $this->client_sock[$client_socket_id];
                         $this->protocol->onConnect($this, $client_socket_id, 0);
                     }
                 } else {
                     $data = Stream::read($socket, $this->buffer_size);
                     if ($data !== false) {
                         $this->protocol->onReceive($this, $socket_id, 0, $data);
                     } else {
                         $this->close($socket_id);
                     }
                 }
             }
         }
     }
 }
示例#2
0
 /**
  * @param int $length
  * @return string
  */
 public function read($length)
 {
     $content = parent::read($length);
     if ($content && !$this->reachedEof) {
         $this->cache .= $content;
     }
     if ($this->eof()) {
         $this->reachedEof = true;
     }
     return $content;
 }
示例#3
0
 function server_loop()
 {
     while ($this->client_sock[0] = stream_socket_accept($this->server_sock, -1)) {
         stream_set_blocking($this->client_sock[0], 1);
         if (feof($this->client_sock[0])) {
             $this->close(0);
         }
         //堵塞Server必须读完全部数据
         $data = Stream::read($this->client_sock[0], $this->buffer_size);
         $this->protocol->onReceive($this, 0, 0, $data);
     }
 }
 public function read($bytes, &$bytes_skipped = null)
 {
     if ($bytes !== 0) {
         $this->current_content .= parent::read($bytes, $bytes_skipped);
     }
     $misc = null;
     $matching_content = $this->scan($this->current_content, $misc);
     if ($matching_content) {
         $found_pos = strpos($this->current_content, $matching_content);
         $bytes_skipped = substr($this->current_content, 0, $found_pos);
         $this->current_content = substr($this->current_content, $found_pos + strlen($matching_content));
         return $this->mutateIn($matching_content, $misc);
     } else {
         if (parent::eof()) {
             $this->current_content = '';
         }
         return null;
     }
 }
 /**
  * @return array|bool
  */
 protected function parseSizeForJPEG()
 {
     $state = null;
     while (true) {
         switch ($state) {
             default:
                 $this->stream->read(2);
                 $state = 'started';
                 break;
             case 'started':
                 $b = $this->getByte();
                 if ($b === false) {
                     return false;
                 }
                 $state = $b == 0xff ? 'sof' : 'started';
                 break;
             case 'sof':
                 $b = $this->getByte();
                 if ($b === 0xe1) {
                     $data = $this->stream->read($this->readInt($this->stream->read(2)) - 2);
                     $stream = new Stream();
                     $stream->write($data);
                     if ($stream->read(4) === 'Exif') {
                         $stream->read(2);
                         $exif = new Faster_Image_B52f1a8_Exif_Parser($stream);
                     }
                     break;
                 }
                 if (in_array($b, range(0xe0, 0xef))) {
                     $state = 'skipframe';
                     break;
                 }
                 if (in_array($b, array_merge(range(0xc0, 0xc3), range(0xc5, 0xc7), range(0xc9, 0xcb), range(0xcd, 0xcf)))) {
                     $state = 'readsize';
                     break;
                 }
                 if ($b == 0xff) {
                     $state = 'sof';
                     break;
                 }
                 $state = 'skipframe';
                 break;
             case 'skipframe':
                 $skip = $this->readInt($this->stream->read(2)) - 2;
                 $this->stream->read($skip);
                 $state = 'started';
                 break;
             case 'readsize':
                 $c = $this->stream->read(7);
                 $size = array($this->readInt(substr($c, 5, 2)), $this->readInt(substr($c, 3, 2)));
                 if (isset($exif) && $exif->isRotated()) {
                     return array_reverse($size);
                 }
                 return $size;
         }
     }
     return false;
 }
示例#6
0
 /**
  * Extracts post-game data (achievements etc) from the body stream.
  *
  * Post-game data will be set on $this->postgameData.
  *
  * @param Stream $stream Body stream to extract from.
  *
  * @return void
  */
 protected function readPostgameData($stream)
 {
     // Prize for ugliest, most boring method of the project goes to…
     $data = new \stdClass();
     $stream->skip(3);
     $stream->read($scenarioFilename, 32);
     $data->scenarioFilename = rtrim($scenarioFilename);
     $stream->skip(4);
     $stream->readInt($data->duration);
     $stream->readChar($data->allowCheats);
     $stream->readChar($data->complete);
     $stream->skip(14);
     $stream->readChar($data->mapSize);
     $stream->readChar($data->mapId);
     $stream->readChar($data->population);
     $stream->skip(1);
     $stream->readChar($data->victory);
     $stream->readChar($data->startingAge);
     $stream->readChar($data->resources);
     $stream->readChar($data->allTechs);
     $stream->readChar($data->teamTogether);
     $stream->readChar($data->revealMap);
     $stream->skip(3);
     $stream->readChar($data->lockTeams);
     $stream->readChar($data->lockSpeed);
     $stream->skip(1);
     $players = array();
     for ($i = 0; $i < 8; $i++) {
         $playerStats = new \stdClass();
         $stream->read($playerName, 16);
         $playerStats->name = rtrim($playerName);
         $stream->readWord($playerStats->totalScore);
         $totalScores = array();
         for ($j = 0; $j < 8; $j++) {
             $stream->readWord($totalScores[$j]);
         }
         $playerStats->totalScores = $totalScores;
         $stream->readChar($playerStats->victory);
         $stream->readChar($playerStats->civId);
         $stream->readChar($playerStats->colorId);
         $stream->readChar($playerStats->team);
         $stream->skip(2);
         $stream->readChar($playerStats->mvp);
         $stream->skip(3);
         $stream->readChar($playerStats->result);
         $stream->skip(3);
         $militaryStats = new \stdClass();
         $stream->readWord($militaryStats->score);
         $stream->readWord($militaryStats->unitsKilled);
         $stream->readWord($militaryStats->u0);
         $stream->readWord($militaryStats->unitsLost);
         $stream->readWord($militaryStats->buildingsRazed);
         $stream->readWord($militaryStats->u1);
         $stream->readWord($militaryStats->buildingsLost);
         $stream->readWord($militaryStats->unitsConverted);
         $playerStats->militaryStats = $militaryStats;
         $stream->skip(32);
         $economyStats = new \stdClass();
         $stream->readWord($economyStats->score);
         $stream->readWord($economyStats->u0);
         $stream->readInt($economyStats->foodCollected);
         $stream->readInt($economyStats->woodCollected);
         $stream->readInt($economyStats->stoneCollected);
         $stream->readInt($economyStats->goldCollected);
         $stream->readWord($economyStats->tributeSent);
         $stream->readWord($economyStats->tributeReceived);
         $stream->readWord($economyStats->tradeProfit);
         $stream->readWord($economyStats->relicGold);
         $playerStats->economyStats = $economyStats;
         $stream->skip(16);
         $techStats = new \stdClass();
         $stream->readWord($techStats->score);
         $stream->readWord($techStats->u0);
         $stream->readInt($techStats->feudalTime);
         $stream->readInt($techStats->castleTime);
         $stream->readInt($techStats->imperialTime);
         $stream->readChar($techStats->mapExploration);
         $stream->readChar($techStats->researchCount);
         $stream->readChar($techStats->researchPercent);
         $playerStats->techStats = $techStats;
         $stream->skip(1);
         $societyStats = new \stdClass();
         $stream->readWord($societyStats->score);
         $stream->readChar($societyStats->totalWonders);
         $stream->readChar($societyStats->totalCastles);
         $stream->readChar($societyStats->relicsCaptured);
         $stream->readChar($societyStats->u0);
         $stream->readWord($societyStats->villagerHigh);
         $playerStats->societyStats = $societyStats;
         $stream->skip(84);
         $players[] = $playerStats;
     }
     $data->players = $players;
     $stream->skip(4);
     $this->postgameData = $data;
 }
示例#7
0
 /**
  * 接收到数据后进行处理
  * @param $client_socket
  * @param $events
  * @param $arg
  * @return unknown_type
  */
 function event_receive($client_socket, $events, $client_id)
 {
     $data = Stream::read($client_socket, $this->buffer_size);
     if ($data !== false) {
         $this->protocol->onReceive($this, $client_id, 0, $data);
     } else {
         $this->close($client_id);
     }
 }
示例#8
0
 /**
  * Waits for the server to send the specified tag back.
  *
  * @param string $tag Tag to wait for from the server.
  *
  * @return boolean|SimpleXMLElement
  */
 protected function waitForServer($tag)
 {
     $this->_logger->debug("Tag we're waiting for: " . $tag);
     $fromServer = false;
     // If there is nothing left in the buffer, wait for the stream to update
     if (count($this->_buffer) == 0 && $this->_stream->select() > 0) {
         $response = '';
         $done = false;
         // Read data from the connection.
         while (!$done) {
             $response .= $this->_stream->read(4096);
             if ($this->_stream->select() == 0) {
                 $done = true;
             }
         }
         $this->_logger->debug('Response (Xmpp_Connection): ' . $response);
         // If the response isn't empty, load it into a SimpleXML element
         if (trim($response) != '') {
             // If the response from the server starts (where "starts
             // with" means "appears after the xml prologue if one is
             // present") with "<stream:stream and it doesn't have a
             // closing "</stream:stream>" then we should append one so
             // that it can be easily loaded into a SimpleXMLElement,
             // otherwise it will cause an error to be thrown because of
             // malformed XML.
             // Check if response starts with XML Prologue:
             if (preg_match("/^<\\?xml version='1.0'( encoding='UTF-8')?\\?>/", $response, $matches) == 1) {
                 $offset = strlen($matches[0]);
                 $prologue = $matches[0];
             } else {
                 $offset = 0;
             }
             // Check if first part of the actual response starts with
             // <stream:stream
             if (strpos($response, '<stream:stream ') === $offset) {
                 // If so, append a closing tag
                 $response .= '</stream:stream>';
             }
             // For consistent handling and correct stream namespace
             // support, we should wrap all responses in the
             // stream:stream tags to make sure everything works as
             // expected. Unless the response already contains such tags.
             if (strpos($response, '<stream:stream') === false) {
                 $response = '<stream:stream ' . 'xmlns:stream="http://etherx.jabber.org/streams" ' . "xmlns:ack='http://www.xmpp.org/extensions/xep-0198.html#ns' " . 'xmlns="jabber:client" ' . 'from="' . $this->_realm . '" ' . 'xml:lang="en" version="1.0">' . $response . '</stream:stream>';
             }
             // If the xml prologue should be at the start, move it
             // because it will now be in the wrong place. We can assume
             // if $offset is not 0 that there was a prologue.
             if ($offset != 0) {
                 $response = $prologue . str_replace($prologue, '', $response);
             }
             $xml = simplexml_load_string($response);
             // If we want the stream element itself, just return that,
             // otherwise check the contents of the stream.
             if ($tag == 'stream:stream') {
                 $fromServer = $xml;
             } else {
                 if ($xml instanceof SimpleXMLElement && $xml->getName() == 'stream') {
                     // Get the namespaces used at the root level of the
                     // document. Add a blank namespace on for anything that
                     // isn't namespaced. Then we can iterate over all of the
                     // elements in the doc.
                     $namespaces = $xml->getNamespaces();
                     $namespaces['blank'] = '';
                     foreach ($namespaces as $namespace) {
                         foreach ($xml->children($namespace) as $child) {
                             if ($child instanceof SimpleXMLElement) {
                                 $this->_buffer[] = $child;
                             }
                         }
                     }
                 }
             }
         }
     }
     $this->_logger->debug('Contents of $fromServer: ' . var_export($fromServer, true));
     $this->_logger->debug('Contents of $this->_buffer before foreach: ' . var_export($this->_buffer, true));
     // Now go over what is in the buffer and return anything necessary
     foreach ($this->_buffer as $key => $stanza) {
         // Only bother looking for more tags if one has not yet been found.
         if ($fromServer === false) {
             // Remove this element from the buffer because we do not want it to
             // be processed again.
             unset($this->_buffer[$key]);
             // If this the tag we want, save it for returning.
             if ($tag == '*' || $stanza->getName() == $tag) {
                 $fromServer = $stanza;
             }
         }
     }
     $this->_logger->debug('Contents of $this->_buffer after foreach: ' . var_export($this->_buffer, true));
     return $fromServer;
 }
示例#9
0
 public function read($length)
 {
     parent::read($length);
     return fread($this->stream, $length);
 }
示例#10
0
 public function positionAfterReOpen()
 {
     $s = new Stream();
     $s->open(STREAM_MODE_WRITE);
     $s->write('GIF89a');
     $s->close();
     $s->open(STREAM_MODE_READ);
     $this->assertEquals(0, $s->tell());
     $this->assertEquals('GIF89a', $s->read());
     $s->close();
 }