网络高级--工具软件的使用

目录

Modbus Slave  &  Poll

 网络调试助手

Wireshark使用

练习:实现poll端功能与slave进行通信


Modbus Slave  &  Poll

1.下载软件,默认安装

2.破解 ,点击connection->connect,输入序列号

3.使用

先设置

 后连接(注意先开启Slave端,后启Poll端)

 查看主机ip地址

win+R键,输入ipconfig

 

 网络调试助手

注意协议发送正确,注意寄存器类型要匹配,先连接后发送

Wireshark使用

捕获器选择:

windows如果连接有线网络,选择本地连接/以太网

如果连接无线网络,选择WLAN

如果只是在本机上的通信,选择NPCAP Loopback apdater

过滤条件:

过滤端口:tcp.port == 502

过滤ip地址:ip.addr == 192.168.xx.xx   (根据自己Windows下的ip地址设置)

练习:实现poll端功能与slave进行通信

分别封装函数实现对保持寄存器的读取和对单个线圈的控制

读保持寄存器:函数参数(寄存器起始地址、寄存器个数、从机ID)

#include <stdio.h>
#include <stdlib.h> // atoi
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>

int sockfd; //定义文件描述符
void set_slave_id(uint8_t *p, int id) //设置从机id
{
    *(p + 6) = id;
}
//读保持寄存器      (发送数据首地址,  功能码,   寄存器地址,寄存器数量,存放接受数据首地址)
void read_registers(uint8_t *p, int function, int addr, int nb, uint8_t *dest)
{
    int i;
    *(p + 5) = 6;              //后面字节数
    *(p + 7) = (char)function; //功能码
    *(p + 8) = addr >> 8;      //寄存器高字节地址
    *(p + 9) = addr & 0xff;    //寄存器低字节地址
    *(p + 10) = nb >> 8;       //寄存器数量高位
    *(p + 11) = nb & 0xff;     //寄存器数量低位
   
/*
           1101 0101 1010 1001
  addr>>8  0000 0000 1101 0101  高字节地址

  addr&0xff 1101 0101 1010 1001
          & 0000 0000 1111 1111
          = 0000 0000 1010 1001 低字节地址

 */
    send(sockfd, p,12,0);//注意这里不能sizeof(p),p为指针
   
    recv(sockfd, dest,64,0);//注意这里不能sizeof(dest),dest为指针
}

void write_coil(uint8_t *p, int function, int addr, int nb, uint8_t *dest)
{
    int i = 0;
    *(p + 5) = 6;              //后面字节数
    *(p + 7) = (char)function; //功能码
    *(p + 8) = addr >> 8;      //线圈高位地址
    *(p + 9) = addr & 0xff;    //线圈低位地址
    if (nb == 1)
        *(p + 10) = 0xff;
    else if (nb == 0)
        *(p + 10) = 0x00;
    *(p + 11) = 0x00;

    send(sockfd, p, 12, 0);
    recv(sockfd, dest, 64, 0);
}

int main(int argc, char const *argv[])
{
    struct sockaddr_in s;

    uint8_t data[12] = {0};
    uint8_t dest[64] = {0};
    int i;

    //1.socket创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err");
        return -1;
    }
    socklen_t len = sizeof(struct sockaddr_in);
    //2.填充结构体
    s.sin_family = AF_INET;                 //协议族
    s.sin_port = htons(atoi(argv[2]));      // htons:小端转大端 atoi:将数字字符串转换为数值
    s.sin_addr.s_addr = inet_addr(argv[1]); //字符串转点分十进制

    //3.connect请求连接
    if (connect(sockfd, (struct sockaddr *)&s, len) < 0)
    {
        perror("connect err");
        return -1;
    }
    //4.设置从机ID
    set_slave_id(data, 1);

    //5.循环发送
    while (1)
    {
        printf("开始读\n");
        read_registers(data, 0x03, 0, 2, dest);
        printf("recv data:");
        for (i = 0; i < dest[8]; i++)
            printf("%d  ", dest[9 + i]);
        printf("\n");
        sleep(5);
        write_coil(data,0x05,0,1,dest);//线圈置一
        printf("线圈置位后:\n");
        printf("%d  %d  \n",dest[10],dest[11]);
        sleep(5);
    }

    //5.关闭套接字
    close(sockfd);
    return 0;
}

运行结果

猜你喜欢

转载自blog.csdn.net/m0_68672255/article/details/130411425
今日推荐