之前我们基本了解了网络通信里的大部分协议,一直都是在“听”的过程。很多人都会觉得,好像看懂了,但关了页面回忆起来,好像又什么都没懂。这次咱们就“真枪实弹”的码起来,再用一个“神器”-网络分析系统详细跟踪下数据包的生命历程,让我们的理论真实的呈现出来,对网络通信感兴趣的博友,还可以自己拿着系统分析一遍,你一定会大有所获。

    不多说,直接上代码。有兴趣的博友可以按各编程语言进行相关改写,然后拿着我们的分析系统真实的看看网络通信过程。

本机请求转发到网关

    代码中的 192.168.1.10 是内网另一台服务器,楼主的 IP 是 192.168.1.73。在本机跑服务器的时候,要做一个路由配置,否则分析系统无法抓取相关的包。window 下可按下面步骤配置:

  1. 管理员身份打开 DOS 窗口;
  2. route add 本机ip mask 255.255.255.255 网关ip(路由转发,还记得吗?忘记了?点我点我点我);

    什么?不知道怎么查 IP 和网关?点我告诉你
    操作完成后记得删除转发规则,否则,你会发现本机的请求,速度会变得很慢、、、
    实例:

// 添加路由转发规则
route add 192.168.1.73 mask 255.255.255.255 192.168.1.1 // 删除转发规则
route delete 192.168.1.73

基于 TCP 的 Socket

    服务端:

<?php
/**
* 1. socket_create: 新建 socket
* 2. socket_bind: 绑定 IP 和 port
* 3. socket_listen: 监听
* 4. socket_accept: 接收客户端连接,返回连接 socket
* 5. socket_read: 读取客户端发送数据
* 6. socket_write: 返回数据
* 7. socket_close: 关闭 socket
*/ $ip = '192.168.1.10';
$port = 23333;
// $port = 80;
$sk = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
!$sk && outInfo('socket_create error'); // 绑定 IP
!socket_bind($sk, $ip, $port) && outInfo('socket_bind error'); // 监听
!socket_listen($sk) && outInfo('sever listen error'); outInfo("Success Listen: $ip:$port", 'INFO');
while (true) {
$accept_res = socket_accept($sk);
!$accept_res && outInfo('sever accept error');
$reqStr = socket_read($accept_res, 1024); if (!$reqStr) outInfo('sever read error');
outInfo("Server receive client msg: $reqStr", 'INFO');
$response = 'Hello A, I am B. you msg is : ' . $reqStr . PHP_EOL;
if (socket_write($accept_res, $response, strlen($response)) === false) {
outInfo('response error');
} socket_close($accept_res);
} socket_close($sk); function outInfo($errMsg, $level = 'ERROR')
{
if ($level === 'ERROR') {
$errMsg = "$errMsg, msg: " . socket_strerror(socket_last_error());
}
echo $errMsg . PHP_EOL;
$level === 'ERROR' && die;
}

    客户端:

<?php
/**
* 1. socket_create: 新建 socket
* 2. socket_connect: 连接服务端
* 3. socket_write: 给服务端发数据
* 4. socket_read: 读取服务端返回的数据
* 5. socket_close: 关闭 socket
*/ $ip = '192.168.1.10';
$port = 23333;
$sk = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
!$sk && outInfo('socket_create error'); !socket_connect($sk, $ip, $port) && outInfo('connect fail');
$msg = 'hello, I am A'; if (socket_write($sk, $msg, strlen($msg)) === false) {
outInfo('socket_write fail');
} while ($res = socket_read($sk, 1024)) {
echo 'server return message is:'. PHP_EOL. $res;
} socket_close($sk);//工作完毕,关闭套接流 function outInfo($errMsg, $level = 'ERROR')
{
if ($level === 'ERROR') {
$errMsg = "$errMsg, msg: " . socket_strerror(socket_last_error());
}
echo $errMsg . PHP_EOL;
$level === 'ERROR' && die;
}

    上面的代码是基于 PHP 原生 Socket 写的,其它语言也有对应 Socket 操作函数,进行相关的改写即可。主要是下面的分析过程。

    如上图,这是我们的分析系统捕捉的所有数据传输过程,你可以真实的看到每一步都发生了什么,以及对应的状态的改变(图片较大,建议右键在新标签页打开看)。

    在图中上半部分,我们可以看到分析系统将整个 TCP 的生命历程分为了三个阶段:建立连接、交易、关闭连接。这和我们之前了解的理论知识完全相符。
    左下角的交易时序图,则详细记录了客户端和服务端每次通信的详细信息,而右下角部分,则展示了每次通信,数据包的状态等信息。

基于 UDP 的Socket

<?php
/**
* 1. socket_create: 新建 socket
* 2. socket_bind: 绑定 IP 和 port
* 3. socket_recvfrom: 读取客户端发送数据
* 4. socket_sendto: 返回数据
* 5. socket_close: 关闭 socket
*/ $ip = '192.168.1.10';
$port = 23333;
$sk = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
!$sk && outInfo('socket_create error'); // 绑定 IP
!socket_bind($sk, $ip, $port) && outInfo('socket_bind error'); outInfo("Success Listen: $ip:$port", 'INFO');
while (true) {
$from = '';
$reqPort = 0;
if (!socket_recvfrom($sk, $buf, 1024, 0, $from, $reqPort)) {
outInfo('sever socket_recvfrom error');
} outInfo("Received msg $buf from remote address $from:$port", 'INFO');
$response = "Hello $from:$port, I am Server. your msg : " . $buf . PHP_EOL;
if (!socket_sendto($sk, $response, strlen($response), 0, $from, $reqPort)) {
outInfo('socket_sendto error');
}
} socket_close($sk); function outInfo($errMsg, $level = 'ERROR')
{
if ($level === 'ERROR') {
$errMsg = "$errMsg, msg: " . socket_strerror(socket_last_error());
}
echo $errMsg . PHP_EOL;
$level === 'ERROR' && die;
}

客户端:

<?php
/**
* 1. socket_create: 新建 socket
* 2. socket_write: 给服务端发数据
* 3. socket_read: 读取服务端返回的数据
* 4. socket_close: 关闭 socket
*/ $ip = '192.168.1.10';
$port = 23333;
$sk = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
!$sk && outInfo('socket_create error'); $msg = 'hello, I am A'; if (!socket_sendto($sk, $msg, strlen($msg), 0, $ip, $port)) {
outInfo('socket_sendto fail');
} $from = '';
$reqPort = 0;
if (!socket_recvfrom($sk, $buf, 1024, 0, $from, $reqPort)) {
outInfo('server socket_recvfrom error');
} outInfo("Received $buf from server address $from:$port", 'INFO'); socket_close($sk); function outInfo($errMsg, $level = 'ERROR')
{
if ($level === 'ERROR') {
$errMsg = "$errMsg, msg: " . socket_strerror(socket_last_error());
}
echo $errMsg . PHP_EOL;
$level === 'ERROR' && die;
}

UDP 数据包分析图:

    如上图,UDP 数据包分析图,明显比 TCP 要简单很多,人家单纯嘛,就不多说了。不过要注意的,写代码的时候,UDP 的服务端,在循环里千万不要关闭 Socket

分析系统介绍

    上面用到的分析系统叫:科来网络分析系统,点我下载。这个分析系统很良心,提供了一个免费的技术交流版。有兴趣的小伙伴可以下载下来玩玩,很强大。

欢迎添加个人微信号:Like若所思。

欢迎关注我的公众号,不仅为你推荐最新的博文,还有更多惊喜和资源在等着你!一起学习共同进步!

网络协议 11 - Socket 编程(下)的更多相关文章

  1. 网络协议 11 - Socket 编程(下):眼见为实耳听为虚

    系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网 ...

  2. 网络协议 10 - Socket 编程(上):实践是检验真理的唯一标准

    系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网 ...

  3. 网络协议 10 - Socket 编程(上)

    前面一直在说各种协议,偏理论方面的知识,这次咱们就来认识下基于 TCP 和 UDP 协议这些理论知识的 Socket 编程.     说 TCP 和 UDP 的时候,我们是分成客户端和服务端来认识的, ...

  4. 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

    Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...

  5. 网络编程基础:网络基础之网络协议、socket模块

    操作系统(简称OS)基础: 应用软件不能直接操作硬件,能直接操作硬件的只有操作系统:所以,应用软件可以通过操作系统来间接操作硬件 网络基础之网络协议: 网络通讯原理: 连接两台计算机之间的Intern ...

  6. 基于TCP协议的socket编程

    什么是socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面, ...

  7. linux网络编程之socket编程(一)

    今天开始,继续来学习linux编程,这次主要是研究下linux下的网络编程,而网络编程中最基本的需从socket编程开始,下面正式开始学习: 什么是socket: 在学习套接口之前,先要回顾一下Tcp ...

  8. 网络协议之:socket协议详解之Socket和Stream Socket

    目录 简介 Socket是什么 Stream Socket 使用socat创建一个TCP服务器 使用ss检查TCP连接 使用nc连接socket 总结 简介 不管是在普通的网络编程中还是在netty中 ...

  9. 关于网络协议和socket编程基本概念

    TCP协议可以说已经是IT人耳熟能详的协议,最近在学习socket网络编程时后重新温习一下这个协议,针对一些问题做了一些总结,很多理解可能还不是很准确. 1. 协议是什么?所谓的各种网络协议无非是一种 ...

随机推荐

  1. laravel学习:主从读写分离配置的实现

    本篇文章给大家带来的内容是关于laravel学习:主从读写分离配置的实现,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在DB的连接工厂中找到以下代码.../vendor/larav ...

  2. vue 复制文本到剪切板上

    1.下载clipboard.js npm install vue-clipboard2 --save 2.引入,可以在mian.js中全局引入也可以在单个vue中引入 import Clipboard ...

  3. java中 Math和StrictMath

    今天无意中看到java api中有StrictMath 这个工具类,发现它部分调用实现是用了Math中的实现.Math 这个类API 1.0版本就有了,StrictMath API是1.3版本才出来的 ...

  4. Java匹马行天下之JavaSE核心技术——注解

    Java注解 一.什么是注解 注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,没有加,则等于没有任何标记,以后,javac编译器.开发工具和其他程序可以通过反射来 ...

  5. 2019-11-29-WPF-笔刷绑定不上可能的原因

    原文:2019-11-29-WPF-笔刷绑定不上可能的原因 title author date CreateTime categories WPF 笔刷绑定不上可能的原因 lindexi 2019-1 ...

  6. DSAPI CMD命令行进程代理

    DSAPI.文件.CMD命令行进程代理,是用来和CMD.exe或指定exe进行输出重定向的简化使用工具,可隐藏或显式地启动一个cmd.exe,并将输出流.输入流和错误流重定向至代理,通过事件触发方式与 ...

  7. vue-Element-axios搭建调用api进行数据展示

    1全局安装vue-cli 输入命令:npm install vue-cli -g 2创建项目框架 输入命令:vue init webpack vueapi 3依次按照提示输入,项目名.项目描述.项目作 ...

  8. mvc5 源码解析2-1:mvchandler的执行

    上一节说在urlroutingmodule中mvchandler 映射到httpcontext上,那mvchandler又是怎么执行的呢? (1).httpruntime 从isapiruntime  ...

  9. laravel 框架配置404等异常页面的方法详解(代码示例)

    本篇文章给大家带来的内容是关于laravel 框架配置404等异常页面的方法详解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在Laravel中所有的异常都由Handl ...

  10. ES6环境搭配(一)

    一.Node(NodeJS.Node.js)的安装:1.下载官网下载地址:https://nodejs.org/en/ 2.安装a.Linux先将安装包解压,然后进行环境变量的配置即可b.window ...