Jump to content

Creating packet for sockets using pack


Artur_Stepien

Recommended Posts

Welcome, I try to build interface to communicate with an application (remote console) using its own protocol and php sockets.

Problem is that I have huge experience using most of php librariers and functions but no experience with

using pack at all, not mention to create packets using it. Second problem is that application does not

respond if packet does not have proper format. I tried to build something using that pack function and

its documentation but packet is more complicated then I thought.

 

Can some one show me how to build proper packet using format on page 2 of this document or at least explain

how to do it properly?

Link to comment
https://forums.phpfreaks.com/topic/285201-creating-packet-for-sockets-using-pack/
Share on other sites

The packet format is two different structures. A Word structure and the overall packet structure. The easiest thing to do would be to create PHP classes to represent these structures and have the classes pack() their own data.

 

For integers, it would have been nice if they had specified big-endian or little-endian. It's unclear to me what format they want however it seems like maybe little-endian is what they want. If it doesn't work with little-endian try big-endian

 

Your Word class might look like this for example:

class Word {
  public $word;
  public function __construct($w){
      $this->word = $w;
  }
  public function pack(){
      return pack('Va*C', strlen($this->word), $this->word, 0);
  }
}

Big thanks for help. This is just learning project to check if communication works. I did created something more based on your code (packet building code) but there is one thing I don't understand in documentation.

This first int32 in packet is 4 bytes long but it contains three parameters (this request/response + server/client + sequence counter). How to make it?

Here is my code. Your class is in word.class.php file

<?php

require_once 'word.class.php';

class Packet {
	public $words = array();
	protected $size = 0;
	protected $is_request;
	protected $from_client;

	/**
	 * Construct packet
	 * 
	 * @param	bool	$is_request	
	 * @param	bool	$is_client
	 * @param	string	$command
	 */
	public function __construct($is_request, $from_client, $command) {
		$this->is_request = $is_request;
		$this->from_client = $from_client;
		
		$this->size +=4 ; // size of first paremeter (4 bytes integer)
		
		$command = trim(preg_replace('!\s+!', ' ', $command)); // remove double spaces
		
		$this->size += strlen( str_ireplace(' ', '', $command) ) ; // size of words
		
		$this->words = explode(' ',$command);
		
		$this->size += count($this->words)*4; // add size of each word size (1 byte for each word)
		
		$this->size += 4; // add size of packet size
		
		$this->size += 4; // size of words count
	}
	
	/**
	 * Return words packet string
	 * 
	 * @return String
	 */
	protected function getWords(){
		$result = '';
		foreach($this->words AS $word) {
			$word = new Word($word);
			$result.= $word->pack();
		}
		
		return $result;
	}

	/**
	 * Return packet for sending
	 * 
	 * @return string
	 */
	public function pack() {
		return pack('VVV', 0, $this->size, count($this->words) ).$this->getWords();
	}

}

Ok, I thing that created correct packet, packet size seems correct so why server returned result once and then each another request now does not return anything?

Here is my corrected code, is something wrong here?:

<?php

require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'word.class.php';

class Packet {
	public $words = array();
	protected $size = 0;
	protected $is_request;
	protected $from_client;

	/**
	 * Construct packet
	 * 
	 * @param	bool	$is_request	
	 * @param	bool	$is_client
	 * @param	string	$command
	 */
	public function __construct($is_request, $from_client, $command) {
		$this->is_request = $is_request;
		$this->from_client = $from_client;
		
		$this->size +=4 ; // size of first paremeter (4 bytes integer)
		
		$command = trim(preg_replace('!\s+!', ' ', $command)); // remove double spaces
		
		$this->size += strlen( str_ireplace(' ', '', $command) ) ; // size of words
		
		$this->words = explode(' ',$command);
		
		$this->size += count($this->words)*5; // add size of each word size + null byte (5 bytes for each word)
		
		$this->size += 4; // add size of packet size
		
		$this->size += 4; // size of words count
	}
	
	/**
	 * Return words packet string
	 * 
	 * @return String
	 */
	protected function getWords(){
		$result = '';
		foreach($this->words AS $word) {
			$word = new Word($word);
			$result.= $word->pack();
		}
		
		return $result;
	}

	/**
	 * Return packet for sending
	 * 
	 * @return string
	 */
	public function pack() {
		return pack('C4VV', (int)$this->is_request, (int)$this->from_client, 0, 0, $this->size, count($this->words) ).$this->getWords();
	}
	
	public function getSize(){
		return $this->size;
	}

}

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.