文章目录
前言
任务:
一、
练习wireshark抓取网络数据包。在两台的电脑(笔记本电脑win10 主机与ubuntu虚拟机。网卡选择桥接模式,可得到两个子网IPv4地址)上运行 “疯狂聊天室”程序,通过wireshark抓包:
1)分析此程序网络连接采用的是哪种协议(TCP、UDP)和什么端口号?
2)试着在抓取包中找到窃取到的聊天信息 (英文字符和汉字可能经过了某种编码转换,数据包中不是明文)
3)如果是网络连接采取的是TCP,分析其建立连接时的3次握手,断开连接时的4次握手;如果是UDP,解释该程序为何能够在多台电脑之间(只有是同一个聊天室编号)同时传输聊天数据?
二、
用C编程完成modbus协议,从云端服务器读取温湿度数据:
软件:
疯狂聊天室:
链接:疯狂聊天室
提取码:1234
wireshark:
链接:wireshark
提取码:1234
RedPandaDE:
链接:RedPandaDE
提取码:1234
一、疯狂聊天室
在进行这个实验时,我们需要两台电脑并且同处于同一局域网下。
1、配置网络
控制面板---->网络和Internet---->网络和共享中心---->更改适配器设置:
禁用其他网关,只留下两台电脑连接的网络:
2、创建房间
两台电脑均需要下载疯狂聊天室:
点击crazychat.exe创建房间:
创建房间号8888,并起名称:
3、互发消息
二、wireshark抓取网络数据包
wireshark的安装一路next、agree即可。
1.找到对应的包
每当我们在疯狂聊天室里发一条消息,wireshark就会即时找到Ip address为广播地址255.255.255.255的包。
从上图抓取到的包分析知:
此聊天程序使用的是UDP协议和255.255.255.255的端口号。
2、分析抓取包中的信息
双击抓取到的包查看具体信息:
数字:
英文:
中文:
由上图分析知:英文字符和数字能够正常明文查看,中文字符进行了编码无法明文查看,在发送三个相同的中文对16进制码进行观察发现,三个字节编码一个汉字,猜测编码格式为UTF-8。
三、Modbus协议概述
1、Modbus协议是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表的。Modbus协议是应用层协议,已经成为工业领域通信协议的业界标准,是工业电子设备之间常用的连接方式。
2、Modbus是一个master/slave架构的协议,有一个节点是master节点,其他使用Modbus协议参与通信的节点是slave节点,每一个slave设备都有一个唯一的地址。只有被指定为master节点的节点可以启动一个命令。所有的Modbus数据帧包含了校验码,保证传输的正确性。基本的ModBus命令能指令一个slave设备改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。
1、Modbus主/从协议原理
Modbus串行链路协议是一个主-从协议。在同一时间,只能将一个主站连接到总线,将一个或多个从站(最大数量为247)连接到相同的串行总线。Modbus 通讯总是由主站发起,当从站没有收到来自主站的请求时,将不会发送数据。主站同时只能启动一个Modbus事务处理,从站之间不能相互通信。
2、通用Modbus帧结构—协议数据单元(PDU)
Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU),特定总线或网络上的Modbus协议映射能够在应用数据单元(ADU)上引入一些附加域。
3、两种Modbus串行传输模式
RTU模式:每个8 Bit字节包含两个4 Bit的十六进制字符,其优点是在同样的波特率下,可比ASCII方式传送更多的数据,但是每个信息必须以连续的数据流传输。
ASCII模式:信息中的每个8 Bit字节需2个ASCII字符,其优点是准许字符的传输间隔达到1s 而不产生错误;
4、ModbusTCP通信结构
Modbus TCP/IP的通信设备:连接至TCP/IP网络的 Modbus TCP/IP客户机和服务器设备。
互连设备如:在TCP/IP网络和串行链路子网之间互连的网桥、路由器或网关等设备。
四、C编程完成modbus协议,从云端服务器读取温湿度数据。
打开RedPandaDE,新建项目:
1、配置代码
1、初始化socket dll,通过IP连接服务器对应端口:
WORD winsock_version = MAKEWORD(2,2);
WSADATA wsa_data;
if (WSAStartup(winsock_version, &wsa_data) != 0) {
printf("Failed to init socket!\n");
return 1;
}
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_socket == INVALID_SOCKET) {
printf("Failed to create server socket!\n");
return 2;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
if (connect(client_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
printf("Failed to connect server: %ld !\n", GetLastError());
return 3;
}
2、生成校验码:
uint16_t CRC_16(uint8_t *temp)
{
uint8_t i,j;
uint16_t CRC_1 = 0xFFFF; //声明CRC寄存区,也就是步骤1