職場でいくつかの機器と通信しようと決心した後、ソケットがどのように機能するかについて頭を悩ませようとしています。基本的な詳細は、機器が UDP 経由で ModBus RTU プロトコルを使用することです。データシートによると、機器はポート 2001 でリッスンし、ポート 2000 に応答します。サンプル コードを見つけようとした後、modbus ライブラリを見つけ、送信と受信が同じように見えるいくつかのシミュレータで動作させることができました。ポート。しかし、私はそれを私の機器で動作させることができないようです。問題はポートに関係していると思います。私はすべてを見てきましたが、有用なものを見つけることができないようです (おそらく、十分に理解していないだけです)。これが私が取り組んでいるコードです。誰かポインタがありますか。
//------------------------------------------------------------------------------
// Copyright (C) 2010, Raditex AB
// All rights reserved.
//
// FreeSCADA
// http://www.FreeSCADA.com
// freescada@freescada.com
//
//------------------------------------------------------------------------------
#include "modbus.h"
#include "modbus-udp.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
int
modbus_udp_close(modbus_udp_handle_t *handle)
{
if (handle == NULL)
return -1;
close(handle->sock);
return 0;
}
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
int
modbus_udp_init(char *host, int port, modbus_udp_handle_t *handle, int delay)
{
struct timeval timeout;
if (handle == NULL)
return -1;
if ((handle->sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
snprintf(modbus_error_str, sizeof(modbus_error_str), "%s: couldn't get socket: %s",
__PRETTY_FUNCTION__, strerror(errno));
return -1;
}
timeout.tv_sec = delay;
timeout.tv_usec = 0;
if (setsockopt(handle->sock, SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(struct timeval)) == -1)
{
snprintf(modbus_error_str, sizeof(modbus_error_str), "%s: couldn't set receive timeout: %s.",
__PRETTY_FUNCTION__, strerror(errno));
return -1;
}
/*
if ((flags = fcntl(handle->sock, F_GETFL, 0)) == -1)
{
snprintf(modbus_error_str, sizeof(modbus_error_str),
"%s: couldn't get fd option non-blocking: F_GETFL.", __PRETTY_FUNCTION__);
return NULL;
}
if (fcntl(io->sock, F_SETFL, flags|O_NONBLOCK) == -1)
{
snprintf(modbus_error_str, sizeof(modbus_error_str),
"%s: couldn't set option non-blocking: F_SETFL.", __PRETTY_FUNCTION__);
return NULL;
}
*/
handle->saddr.sin_family = AF_INET;
if ((handle->addr = gethostbyname(host)) == NULL)
{
snprintf(modbus_error_str, sizeof(modbus_error_str), "%s: couldn't get host: %s: %s",
__PRETTY_FUNCTION__, strerror(errno), host);
return -1;
}
bcopy((char *) handle->addr->h_addr,
(char *)&handle->saddr.sin_addr,
handle->addr->h_length);
handle->saddr.sin_port = htons(port);
return 0;
}
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
int
modbus_udp_send(modbus_udp_handle_t *handle, modbus_packet_t *pkt)
{
char buff[256];
int len;
if (pkt == NULL)
return -1;
len = modbus_packet_pack(pkt, buff, sizeof(buff));
if (sendto(handle->sock, buff, len, 0, (struct sockaddr *)&handle->saddr, sizeof(handle->saddr)) != len)
{
snprintf(modbus_error_str, sizeof(modbus_error_str),
"%s: failed to send modbus UDP packet", __PRETTY_FUNCTION__);
return -1;
}
return 0;
}
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
int
modbus_udp_recv(modbus_udp_handle_t *handle, modbus_packet_t *pkt)
{
socklen_t fromlen;
struct sockaddr_in caller;
char buff[256];
int len;
// read UDP data
fromlen = sizeof (caller);
if ((len = recvfrom(handle->sock, buff, sizeof(buff), 0, (struct sockaddr *)&caller, &fromlen)) > 0)
{
return modbus_packet_parse(pkt, buff, len);
}
return -1;
}