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
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);
  }
}
Link to comment
Share on other sites

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();
	}

}
Link to comment
Share on other sites

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;
	}

}
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.