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

系列文章传送门:

  1. 网络协议 1 - 概述
  2. 网络协议 2 - IP 是怎么来,又是怎么没的?
  3. 网络协议 3 - 从物理层到 MAC 层
  4. 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校
  5. 网络协议 5 - ICMP 与 ping:投石问路的侦察兵
  6. 网络协议 6 - 路由协议:敢问路在何方?
  7. 网络协议 7 - UDP 协议:性善碰到城会玩
  8. 网络协议 8 - TCP 协议(上):性恶就要套路深
  9. 网络协议 9 - TCP协议(下):聪明反被聪明误
  10. 网络协议 10 - Socket 编程(上):实践是检验真理的唯一标准

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

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

本机请求转发到网关

    代码中的 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

分析系统介绍

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

posted on 2019-04-29 10:03 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10788729.html

网络协议 11 - Socket 编程(下):眼见为实耳听为虚相关推荐

  1. 网络协议 11 - Socket 编程(下)

    之前我们基本了解了网络通信里的大部分协议,一直都是在"听"的过程.很多人都会觉得,好像看懂了,但关了页面回忆起来,好像又什么都没懂.这次咱们就"真枪实弹"的码起 ...

  2. java socket 通信协议_java 基于TCP协议的Socket编程和通信

    java 基于 TCP 协议的 Socket 编程和通信 在网络通讯中,第一次主动发起通讯的程序被称作客户 端 (Client) 程序, 简称客户端, 而在第一次通讯中等待连接的 程序被称作服务器端 ...

  3. Sockey编程之基于 UDP 协议的 Socket 编程

    一.基于 UDP 协议的 Socket 编程 1.端口选择 已知端口:0~1023,为固定服务保留. 已注册的端口:1024~49151,供普通用户的普通用户进程或程序使用. 动态或私用端口: 491 ...

  4. 【socket】从计算机网络基础到socket编程——Windows Linux C语言 + Python实现(TCP+UDP)

    一.部分基础知识 1.1 计算机网络的体系结构 1.11 互联网简介 1.12 计算机网络的分类 1.13 协议与网络的分层体系结构 ▶ 协议 ▶ 网络的分层体系结构 1.14 OSI 七层模型(重要 ...

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

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

  6. 基于Socket编程下 实现Linux-Linux、Linux-Windows tcp通信

    文章目录 前言 一.Linux - Linux 服务器 server 客户端 client 通信实操 二.socket编程在windows和linux下的区别 三.Windows - Linux 四. ...

  7. 华中科技大学计算机通信与网络实验,华中科技大学计算机通信与网络实验报告Socket编程实验.docx...

    实验一 Socket编程实验 1.1环境 开发环境:Windows 10 64 位,Intel Core i5-7300HQ CPU, 8GB 内存 1.1. 1开发平台 Microsoft Visu ...

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

    文章目录 简介 什么是Datagram Socket 使用socat来创建UDP服务 使用ss命令来监控Datagram Sockets 使用nc建立和UDP Socket的连接 总结 简介 上一篇文 ...

  9. 网络编程之 socket编程

    socket编程(基于linux下的网络编程) 提起网络编程那么我们就不得不说一下socket编程了(本博客主要是围绕下面这本书展开的). 感谢bingo大佬提供的书籍 链接: https://pan ...

最新文章

  1. 共享一些知识点的学习地址
  2. BUG管理系统(Mantis)迁移实录
  3. opencv 标记有数字的区域
  4. 视觉SLAM学习--视觉定位比赛(CVPR2020)
  5. 数值计算动态语言Julia 1.0发布
  6. 3.2.4 OS之页面分配策略(驻留集、页面分配、置换策略、抖动现象、工作集)
  7. LinkedList阅读
  8. Linux内存page,【原创】(十四)Linux内存管理之page fault处理
  9. Linux下Oracle数据库的搭建(新手)
  10. 三类测量血压原理 - 智能手环测血压原理详解
  11. 用SignalR 2.0开发客服系统[系列5:使用SignalR的中文简体语言包和其他技术点]
  12. HyperLedger Composer升级fabric链码
  13. Oracle10g安装教程、配置实例、监听、客户端程序详解_Windows篇
  14. 【钉钉-场景化能力包】阿里商旅助力费控报销
  15. 离散数学-代数系统4-同构
  16. 如何写好一篇论文——闵老师《论文写作》心得
  17. Unity3D——学习分享(二) 给游戏对象添加材质和贴图
  18. OJ old1226 算法提高 质数的后代
  19. 109:vue+openlayers 定位动画(平移-弹性平移-飞行 示例代码)
  20. windows10纯净版系统安装/重装详细教程

热门文章

  1. 802.11协议:wifi
  2. 改进的判定条件覆盖讲解和真值表书写
  3. [译] 2019 前端性能优化年度总结 — 第五部分
  4. 一道按顺序排列组合题的几种解法
  5. 使用tk.mapper和pagehelper一个bug记录:没有为 'PAGE_TABLE_ALIAS' 的列 4 指定任何列名称
  6. 个人腾讯云服务器的搭建
  7. 记录h5文件数据转为npy和csv格式类型的方法
  8. STM32在CubeMX下HAl库编程MISO为何设置和MOSI相同
  9. Vue清除定时器优化方案
  10. IDEA与GitHub的仓库相关联,幼儿园教学(狗头保命)