कुछ उदाहरण
उदाहरण एक
प्रोटोकॉल परिभाषा
- हेडर की लंबाई 10 बाइट्स है जो पूरे डेटा पैकेज की लंबाई को संग्रहीत करती है, यदि बाइट्स की कमी हो तो 0 से भरें
- डेटा प्रारूप xml है
डेटा पैकेज का उदाहरण
0000000121<?xml version="1.0" encoding="ISO-8859-1"?>
<request>
<module>user</module>
<action>getInfo</action>
</request>
जहां 0000000121 पूरे डेटा पैकेज की लंबाई का प्रतिनिधित्व करता है, उसके बाद xml डेटा प्रारूप का पैकेज सामग्री आती है।
प्रोटोकॉल कार्यान्वयन
namespace Protocols;
class XmlProtocol
{
public static function input($recv_buffer)
{
if(strlen($recv_buffer) < 10)
{
// 10 बाइट्स पर्याप्त नहीं, 0 लौटाएँ, डेटा का इंतजार करें
return 0;
}
// पैकेज की लंबाई लौटाएँ, पैकेज की लंबाई में हेडर डेटा की लंबाई + पैकेज सामग्री की लंबाई शामिल है
$total_len = base_convert(substr($recv_buffer, 0, 10), 10, 10);
return $total_len;
}
public static function decode($recv_buffer)
{
// अनुरोध पैकेज सामग्री
$body = substr($recv_buffer, 10);
return simplexml_load_string($body);
}
public static function encode($xml_string)
{
// पैकेज सामग्री + पैकेज हेडर की लंबाई
$total_length = strlen($xml_string)+10;
// लंबाई के हिस्से को 10 बाइट्स पूरा करें, यदि बाइट्स की कमी हो तो 0 से भरें
$total_length_str = str_pad($total_length, 10, '0', STR_PAD_LEFT);
// डेटा लौटाएँ
return $total_length_str . $xml_string;
}
}
उदाहरण दो
प्रोटोकॉल परिभाषा
- हेडर 4 बाइट्स का नेटवर्क बाइट ऑर्डर unsigned int, पूरे पैकेज की लंबाई चिह्नित करता है
- डेटा भाग Json स्ट्रिंग है
डेटा पैकेज का उदाहरण
****{"type":"message","content":"hello all"}
जहां हेडर के चार बाइट्स * अंक एक नेटवर्क बाइट ऑर्डर के unsigned int डेटा को दर्शाते हैं, जो अदृश्य वर्ण है, उसके तुरंत बाद Json डेटा प्रारूप का पैकेज सामग्री है।
प्रोटोकॉल कार्यान्वयन
namespace Protocols;
class JsonInt
{
public static function input($recv_buffer)
{
// प्राप्त डेटा 4 बाइट्स से कम है, पैकेज की लंबाई ज्ञात नहीं है, 0 लौटाएँ डेटा का इंतजार करें
if(strlen($recv_buffer)<4)
{
return 0;
}
// unpack फ़ंक्शन का उपयोग करके हेडर के 4 बाइट्स को संख्या में परिवर्तित करें, हेडर के 4 बाइट्स पूरे डेटा पैकेज की लंबाई होती है
$unpack_data = unpack('Ntotal_length', $recv_buffer);
return $unpack_data['total_length'];
}
public static function decode($recv_buffer)
{
// हेडर के 4 बाइट्स को हटा दें, पैकेज की Json डेटा प्राप्त करें
$body_json_str = substr($recv_buffer, 4);
// json डिकोड करें
return json_decode($body_json_str, true);
}
public static function encode($data)
{
// Json encoding के जरिए पैकेज सामग्री प्राप्त करें
$body_json_str = json_encode($data);
// पूरे पैकेज की लंबाई की गणना करें, हेडर के 4 बाइट्स + पैकेज सामग्री बाइट्स की संख्या
$total_length = 4 + strlen($body_json_str);
// पैकेज किए गए डेटा लौटाएँ
return pack('N',$total_length) . $body_json_str;
}
}
उदाहरण तीन (बाइनरी प्रोटोकॉल का उपयोग करके फ़ाइल अपलोड करना)
प्रोटोकॉल परिभाषा
struct
{
unsigned int total_len; // पूरे पैकेज की लंबाई, बड़े अंत नेटवर्क बाइट ऑर्डर
char name_len; // फ़ाइल नाम की लंबाई
char name[name_len]; // फ़ाइल नाम
char file[total_len - BinaryTransfer::PACKAGE_HEAD_LEN - name_len]; // फ़ाइल डेटा
}
प्रोटोकॉल का उदाहरण
*****logo.png******************
जहां हेडर के चार बाइट्स अंक एक नेटवर्क बाइट ऑर्डर के unsigned int डेटा को दर्शाते हैं, जो अदृश्य वर्ण है, 5वां एक बाइट में फ़ाइल नाम की लंबाई संग्रहीत करता है, इसके तुरंत बाद फ़ाइल नाम, और फिर असली बाइनरी फ़ाइल डेटा आता है।
प्रोटोकॉल कार्यान्वयन
namespace Protocols;
class BinaryTransfer
{
// प्रोटोकॉल हेडर की लंबाई
const PACKAGE_HEAD_LEN = 5;
public static function input($recv_buffer)
{
// यदि एक प्रोटोकॉल हेडर की लंबाई पर्याप्त नहीं है, तो इंतजार करें
if(strlen($recv_buffer) < self::PACKAGE_HEAD_LEN)
{
return 0;
}
// अनपैक करें
$package_data = unpack('Ntotal_len/Cname_len', $recv_buffer);
// पैकेज की लंबाई लौटाएँ
return $package_data['total_len'];
}
public static function decode($recv_buffer)
{
// अनपैक करें
$package_data = unpack('Ntotal_len/Cname_len', $recv_buffer);
// फ़ाइल नाम की लंबाई
$name_len = $package_data['name_len'];
// डेटा स्ट्रीम से फ़ाइल नाम निकालें
$file_name = substr($recv_buffer, self::PACKAGE_HEAD_LEN, $name_len);
// डेटा स्ट्रीम से फ़ाइल बाइनरी डेटा निकालें
$file_data = substr($recv_buffer, self::PACKAGE_HEAD_LEN + $name_len);
return array(
'file_name' => $file_name,
'file_data' => $file_data,
);
}
public static function encode($data)
{
// आप अपनी जरूरतों के अनुसार क्लाइंट को भेजे जाने वाले डेटा को एन्कोड कर सकते हैं, यहां इसे सीधे टेक्स्ट के रूप में लौटाया गया है
return $data;
}
}
सर्वर प्रोटोकॉल उपयोग उदाहरण
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('BinaryTransfer://0.0.0.0:8333');
// फ़ाइल को tmp में सेव करें
$worker->onMessage = function(TcpConnection $connection, $data)
{
$save_path = '/tmp/'.$data['file_name'];
file_put_contents($save_path, $data['file_data']);
$connection->send("upload success. save path $save_path");
};
Worker::runAll();
क्लाइंट फ़ाइल client.php (यहां php का उपयोग करके क्लाइंट अपलोड करना अनुकरण किया गया है)
<?php
/** फ़ाइल अपलोड क्लाइंट **/
// अपलोड पते
$address = "127.0.0.1:8333";
// अपलोड फ़ाइल पथ पैरामीटर की जांच करें
if(!isset($argv[1]))
{
exit("use php client.php \$file_path\n");
}
// अपलोड फ़ाइल का पथ
$file_to_transfer = trim($argv[1]);
// अपलोड की गई फ़ाइल स्थानीय रूप से मौजूद नहीं है
if(!is_file($file_to_transfer))
{
exit("$file_to_transfer not exist\n");
}
// सॉकेट कनेक्शन स्थापित करें
$client = stream_socket_client($address, $errno, $errmsg);
if(!$client)
{
exit("$errmsg\n");
}
// ब्लॉकिंग पर सेट करें
stream_set_blocking($client, 1);
// फ़ाइल नाम
$file_name = basename($file_to_transfer);
// फ़ाइल नाम की लंबाई
$name_len = strlen($file_name);
// फ़ाइल बाइनरी डेटा
$file_data = file_get_contents($file_to_transfer);
// प्रोटोकॉल हेडर की लंबाई 4 बाइट्स पैकेज लंबाई + 1 बाइट फ़ाइल नाम की लंबाई
$PACKAGE_HEAD_LEN = 5;
// प्रोटोकॉल पैकेज
$package = pack('NC', $PACKAGE_HEAD_LEN + strlen($file_name) + strlen($file_data), $name_len) . $file_name . $file_data;
// अपलोड निष्पादित करें
fwrite($client, $package);
// परिणाम प्रिंट करें
echo fread($client, 8192),"\n";
क्लाइंट उपयोग उदाहरण
कमांड लाइन में चलाएँ php client.php <फ़ाइल पथ>
जैसे php client.php abc.jpg
उदाहरण चार (टेक्स्ट प्रोटोकॉल का उपयोग करके फ़ाइल अपलोड करना)
प्रोटोकॉल परिभाषा
json+newline, json में फ़ाइल नाम और base64_encode एन्कोडेड (जो आकार को 1/3 बढ़ा देगा) फ़ाइल डेटा शामिल है
प्रोटोकॉल का उदाहरण
{"file_name":"logo.png","file_data":"PD9waHAKLyo......"}\n
ध्यान दें कि अंत में एक newline है, PHP में इसे डबल कोट कैरेक्टर "\n" से दर्शाया जाता है।
प्रोटोकॉल कार्यान्वयन
namespace Protocols;
class TextTransfer
{
public static function input($recv_buffer)
{
$recv_len = strlen($recv_buffer);
if($recv_buffer[$recv_len-1] !== "\n")
{
return 0;
}
return strlen($recv_buffer);
}
public static function decode($recv_buffer)
{
// अनपैक करें
$package_data = json_decode(trim($recv_buffer), true);
// फ़ाइल नाम निकालें
$file_name = $package_data['file_name'];
// base64_encode के बाद फ़ाइल डेटा निकालें
$file_data = $package_data['file_data'];
// base64_decode करके मूल बाइनरी फ़ाइल डेटा में वापस लौटें
$file_data = base64_decode($file_data);
// डेटा लौटाएँ
return array(
'file_name' => $file_name,
'file_data' => $file_data,
);
}
public static function encode($data)
{
// आप अपनी जरूरतों के अनुसार क्लाइंट को भेजे जाने वाले डेटा को एन्कोड कर सकते हैं, यहां इसे सीधे टेक्स्ट के रूप में लौटाया गया है
return $data;
}
}
सर्वर प्रोटोकॉल उपयोग उदाहरण
व्याख्या: बाइनरी अपलोड के तरीके के समान है, अर्थात, किसी भी व्यवसायिक कोड को बिना किसी बदलाव के प्रोटोकॉल को स्विच करना संभव हो गया है।
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('TextTransfer://0.0.0.0:8333');
// फ़ाइल को tmp में सेव करें
$worker->onMessage = function(TcpConnection $connection, $data)
{
$save_path = '/tmp/'.$data['file_name'];
file_put_contents($save_path, $data['file_data']);
$connection->send("upload success. save path $save_path");
};
Worker::runAll();
क्लाइंट फ़ाइल textclient.php (यहां php का उपयोग करके क्लाइंट अपलोड करना अनुकरण किया गया है)
<?php
/** फ़ाइल अपलोड क्लाइंट **/
// अपलोड पते
$address = "127.0.0.1:8333";
// अपलोड फ़ाइल पथ पैरामीटर की जांच करें
if(!isset($argv[1]))
{
exit("use php client.php \$file_path\n");
}
// अपलोड फ़ाइल का पथ
$file_to_transfer = trim($argv[1]);
// अपलोड की गई फ़ाइल स्थानीय रूप से मौजूद नहीं है
if(!is_file($file_to_transfer))
{
exit("$file_to_transfer not exist\n");
}
// सॉकेट कनेक्शन स्थापित करें
$client = stream_socket_client($address, $errno, $errmsg);
if(!$client)
{
exit("$errmsg\n");
}
stream_set_blocking($client, 1);
// फ़ाइल नाम
$file_name = basename($file_to_transfer);
// फ़ाइल बाइनरी डेटा
$file_data = file_get_contents($file_to_transfer);
// base64 एन्कोडिंग
$file_data = base64_encode($file_data);
// डेटा पैकेज
$package_data = array(
'file_name' => $file_name,
'file_data' => $file_data,
);
// प्रोटोकॉल पैकेज json+newline
$package = json_encode($package_data)."\n";
// अपलोड निष्पादित करें
fwrite($client, $package);
// परिणाम प्रिंट करें
echo fread($client, 8192),"\n";
क्लाइंट उपयोग उदाहरण
कमांड लाइन में चलाएँ php textclient.php <फ़ाइल पथ>
जैसे php textclient.php abc.jpg