2013-04-02 81 views
0

我試圖總結我的周圍插座決定試着跟一些設備在工作後是如何工作的負責人。基本的細節是設備通過UDP使用ModBus RTU協議。數據表說,該設備偵聽端口2001,並回復給端口2000年試圖找到一些示例代碼,我發現一個Modbus庫後,並設法得到它與一些模擬器,其中發送和接收工作,似乎是在同港口。但是,我似乎無法讓它與我的設備一起工作。我認爲這個問題與港口有關。我到處都找過,似乎不能露面任何有用的東西(也許我只是沒有足夠好的理解)。這是我正在使用的代碼,有沒有人有任何指針。UDP的sendto和recvfrom在不同的端口

//------------------------------------------------------------------------------ 
// Copyright (C) 2010, Raditex AB 
// All rights reserved. 
// 
// FreeSCADA 
// http://www.FreeSCADA.com 
// [email protected] 
// 
//------------------------------------------------------------------------------ 

#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; 
} 

回答

2

數據表說,該設備偵聽端口2001,並回復給端口2000

這意味着你需要創建一個套接字並bind()它在端口本地IP 2000,然後sendto()設備的IP在端口2001上。您顯示的代碼根本不會調用bind(),因此沒有用於接收數據的本地端口recvfrom()

+0

謝謝,我會研究如何做到這一點。 – madpenguin8

相關問題