网络协议 11 - Socket 编程(下)
之前我们基本了解了网络通信里的大部分协议,一直都是在“听”的过程。很多人都会觉得,好像看懂了,但关了页面回忆起来,好像又什么都没懂。这次咱们就“真枪实弹”的码起来,再用一个“神器”-网络分析系统详细跟踪下数据包的生命历程,让我们的理论真实的呈现出来,对网络通信感兴趣的博友,还可以自己拿着系统分析一遍,你一定会大有所获。
不多说,直接上代码。有兴趣的博友可以按各编程语言进行相关改写,然后拿着我们的分析系统真实的看看网络通信过程。
本机请求转发到网关
代码中的 192.168.1.10 是内网另一台服务器,楼主的 IP 是 192.168.1.73。在本机跑服务器的时候,要做一个路由配置,否则分析系统无法抓取相关的包。window 下可按下面步骤配置:
- 管理员身份打开 DOS 窗口;
- 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 编程(下)的更多相关文章
- 网络协议 11 - Socket 编程(下):眼见为实耳听为虚
系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网 ...
- 网络协议 10 - Socket 编程(上):实践是检验真理的唯一标准
系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网 ...
- 网络协议 10 - Socket 编程(上)
前面一直在说各种协议,偏理论方面的知识,这次咱们就来认识下基于 TCP 和 UDP 协议这些理论知识的 Socket 编程. 说 TCP 和 UDP 的时候,我们是分成客户端和服务端来认识的, ...
- 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程
Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...
- 网络编程基础:网络基础之网络协议、socket模块
操作系统(简称OS)基础: 应用软件不能直接操作硬件,能直接操作硬件的只有操作系统:所以,应用软件可以通过操作系统来间接操作硬件 网络基础之网络协议: 网络通讯原理: 连接两台计算机之间的Intern ...
- 基于TCP协议的socket编程
什么是socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面, ...
- linux网络编程之socket编程(一)
今天开始,继续来学习linux编程,这次主要是研究下linux下的网络编程,而网络编程中最基本的需从socket编程开始,下面正式开始学习: 什么是socket: 在学习套接口之前,先要回顾一下Tcp ...
- 网络协议之:socket协议详解之Socket和Stream Socket
目录 简介 Socket是什么 Stream Socket 使用socat创建一个TCP服务器 使用ss检查TCP连接 使用nc连接socket 总结 简介 不管是在普通的网络编程中还是在netty中 ...
- 关于网络协议和socket编程基本概念
TCP协议可以说已经是IT人耳熟能详的协议,最近在学习socket网络编程时后重新温习一下这个协议,针对一些问题做了一些总结,很多理解可能还不是很准确. 1. 协议是什么?所谓的各种网络协议无非是一种 ...
随机推荐
- laravel学习:主从读写分离配置的实现
本篇文章给大家带来的内容是关于laravel学习:主从读写分离配置的实现,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在DB的连接工厂中找到以下代码.../vendor/larav ...
- vue 复制文本到剪切板上
1.下载clipboard.js npm install vue-clipboard2 --save 2.引入,可以在mian.js中全局引入也可以在单个vue中引入 import Clipboard ...
- java中 Math和StrictMath
今天无意中看到java api中有StrictMath 这个工具类,发现它部分调用实现是用了Math中的实现.Math 这个类API 1.0版本就有了,StrictMath API是1.3版本才出来的 ...
- Java匹马行天下之JavaSE核心技术——注解
Java注解 一.什么是注解 注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,没有加,则等于没有任何标记,以后,javac编译器.开发工具和其他程序可以通过反射来 ...
- 2019-11-29-WPF-笔刷绑定不上可能的原因
原文:2019-11-29-WPF-笔刷绑定不上可能的原因 title author date CreateTime categories WPF 笔刷绑定不上可能的原因 lindexi 2019-1 ...
- DSAPI CMD命令行进程代理
DSAPI.文件.CMD命令行进程代理,是用来和CMD.exe或指定exe进行输出重定向的简化使用工具,可隐藏或显式地启动一个cmd.exe,并将输出流.输入流和错误流重定向至代理,通过事件触发方式与 ...
- vue-Element-axios搭建调用api进行数据展示
1全局安装vue-cli 输入命令:npm install vue-cli -g 2创建项目框架 输入命令:vue init webpack vueapi 3依次按照提示输入,项目名.项目描述.项目作 ...
- mvc5 源码解析2-1:mvchandler的执行
上一节说在urlroutingmodule中mvchandler 映射到httpcontext上,那mvchandler又是怎么执行的呢? (1).httpruntime 从isapiruntime ...
- laravel 框架配置404等异常页面的方法详解(代码示例)
本篇文章给大家带来的内容是关于laravel 框架配置404等异常页面的方法详解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在Laravel中所有的异常都由Handl ...
- ES6环境搭配(一)
一.Node(NodeJS.Node.js)的安装:1.下载官网下载地址:https://nodejs.org/en/ 2.安装a.Linux先将安装包解压,然后进行环境变量的配置即可b.window ...