使用 Telnet 调试 TCP
像 redis,beanstalk,memcached 都是基于 TCP 的,有的时候需要直接通过 TCP 调试与传输数据,比如编写客户端插件,使用 telnet 可以很方便地进行调试。
调试 redis:
% telnet localhost 6379 Trying ::1... Connected to localhost. Escape character is '^]'.
然后可以直接交互式执行命令了:
% telnet localhost 6379 Trying ::1... Connected to localhost. Escape character is '^]'. set a hello +OK get a $5 hello
编写客户端就是建立 socket 连接,然后把这些命令发送过去,然后解析返回的数据而已。
<?php /** * Created by human. * User: Weinan Tang <twn39@163.com> * Date: 2018-12-29 * Time: 15:36 */ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_bind($socket, '0.0.0.0'); $result = socket_connect($socket, '121.199.44.30', 11300); function get_line($socket) { $buffer = ''; $result = ''; while ($buffer !== "\n") { $buffer = socket_read($socket, 1024, PHP_NORMAL_READ); $result .= $buffer; } $head = explode(' ', trim($result)); return $head; } function get_body($socket, $length) { $buffer = socket_read($socket, $length + strlen("\r\n"), PHP_BINARY_READ); return $buffer; } function execute($command, $socket) { socket_write($socket, $command."\r\n"); $head = get_line($socket); $body = ''; if ($head[0] === strtoupper('reserved')) { $body = get_body($socket, $head[2]); } $content = [ 'head' => $head, 'body' => $body, ]; var_dump($content); return $content; } socket_set_block($socket); $result = execute('use feed', $socket); $result = execute('watch feed', $socket); $result = execute('ignore default', $socket); while (true) { $result = execute('reserve', $socket); }
<?php class Sockets { private $socket; private $host; private $port; public function __construct($host, $port) { $this->host = $host; $this->port = $port; $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_connect($this->socket, $this->host, $this->port); } public function execute($command) { socket_write($this->socket, $command."\r\n"); $head = $this->getLine(); $body = ''; if ($this->hasBody($head[0])) { $length = strtolower($head[0]) === 'ok' ? $head[1]:$head[2]; $body = $this->getBody($length); } return [ 'head' => $head, 'body' => $body, ]; } public function hasBody($keyword) { $longCommand = ['reserved', 'ok']; return in_array(strtolower($keyword), $longCommand); } public function getLine() { $buffer = ''; $result = ''; while ($buffer !== "\n") { $buffer = socket_read($this->socket, 1024, PHP_NORMAL_READ); $result .= $buffer; } return explode(' ', trim($result)); } public function getBody($length) { return socket_read($this->socket, $length + strlen("\r\n"), PHP_BINARY_READ); } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论