Проблема с отправкой 2-го кода команды на устройство через Modbus TCP - PullRequest
1 голос
/ 22 марта 2020

Я новичок и у меня проблемы с отправкой сообщений через Modbus TCP. Я создаю win-сокет с RFID-головкой чтения / записи на порту 502, затем отправляю 1-ю команду 10h (write_multiple_registers) в head и получаю ответ без проблем ... После этого я думаю, что готов отправить следующую команду (снова 10h или 03h (read_holding_registers), но он не работает. Я должен создать новый сокет, а затем он работает, пока не выполнится первая команда ... Кажется, что RFID-головка не получает команду. Я обычно использую send () и recv () Я пытался протестировать устройство с помощью тестера, например SimplyModbus, и все работает без проблем. У кого-нибудь есть опыт решения этой проблемы? Большое спасибо за помощь!

#ifndef PCH_H
#define PCH_H
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <Winsock2.h>
#include <WS2tcpip.h>
#include <string>
#include <iostream>

#include <stdio.h>
#include <conio.h>


#pragma comment (lib,"WS2_32.lib")

using namespace std;
using std::string;
typedef SSIZE_T ssize_t;

#endif //PCH_H

bool modbus::modbus_connect() {
    if(HOST == "" || PORT == 0) {
        std::cout << "Missing Host and Port" << std::endl;
        return false;
    } else {
        std::cout << "Found Proper Host "<< HOST << " and Port " <<PORT <<std::endl;
    }

    WSAData data;
    sockaddr_in _server;
    WORD ver = MAKEWORD(2, 2);
    wsResult = WSAStartup(ver, &data);
    if (wsResult != 0)
    {
        cerr << "Error Create Socket" << wsResult << endl;
        return false;
    }

    _socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(_socket == -1) {
        std::cout <<"Error Opening Socket" <<std::endl;
        return false;
    } else {
        std::cout <<"Socket Opened Successfully" << std::endl;
    }

    u_long iMode = 0;
    wsResult = ioctlsocket(_socket, FIONBIO, &iMode);

    _server.sin_family = AF_INET;
    _server.sin_addr.s_addr = inet_addr(HOST.c_str());
    _server.sin_port = htons(PORT);

    wsResult = ::bind(_socket,(sockaddr*)&_server, sizeof(_server));


    if (connect(_socket, (sockaddr*)&_server, sizeof(_server)) < 0) {
        std::cout<< "Connection Error" << std::endl;
        return false;
    }

    std::cout<< "Connected" <<std::endl;
    _connected = true;
    return true;
}

ssize_t modbus::modbus_send(uint8_t *to_send, int length)
{
    FD_ZERO(&fds);
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    FD_SET(_socket, &fds);
    int i = select(32, NULL, &fds, NULL, &tv); // write
    if (i <= 0)
    {
        printf("select - error %d\n", WSAGetLastError());
        closesocket(_socket);
        WSACleanup();
        return 1;
    }
    _msg_id++;

    wsResult = send(_socket, (const char*)to_send, (size_t)length, 0);
    if (wsResult == SOCKET_ERROR)
    {
        printf("send failed with error: %d\n", WSAGetLastError());
        WSACleanup();
    }

    return 0;
}

ssize_t modbus::modbus_receive(uint8_t *buffer)
{
    FD_ZERO(&fds);
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    FD_SET(_socket, &fds);
    int i = select(32, &fds, NULL, NULL, &tv); //read
    if (i <= 0)
    {
        printf("no TCP response received\n");
        closesocket(_socket);
        WSACleanup();
        return 1;
    }

    wsResult = recv(_socket, (char *)buffer, 1024, 0);
    if (wsResult == 0)
    {
        printf("received failed with error: %d\n", WSAGetLastError());
        WSACleanup();

    }
    return 0;
}



...