2

我首先要说我是一名几乎没有 c++ 经验的大学生。你听过多少次是对的?我正在使用 libnodave 库中的测试程序 testISO_TCP(简化版)。该程序在连接到 seimens 300 PLC 时对标志值和数据块进行简单读取。该程序本身不会产生任何错误。我想要做的是希望在这个程序中添加一些代码,以保护读取不会崩溃。让我解释得更好一点。例如,我在代码中实现了很多读取。到目前为止,只有两个读取。最终,我将通过更多读取来运行此代码。现在,假设我正在运行测试程序,但由于某种原因我失去了与 PLC 的连接。我想让程序做两件事之一:1)一旦连接丢失,进行一定次数的重试连接,当尝试次数用完时,退出。或 2) 不知何故继续从 PLC 读取,直到它们全部完成。

我希望这是足够的信息来获得一些帮助。我将发布我长期以来一直在寻找的代码,但不知道如何有效地做到这一点。提前感谢大家。

#define PLAY_WITH_KEEPALIVE
#include <stdlib.h>
#include <stdio.h>
#include "nodavesimple.h"
#include "openSocket.h"


#ifdef PLAY_WITH_KEEPALIVE
#include <winsock.h>
#endif


int main(int argc, char **argv) {
    int a,b,c,res, doRun, doStop, doRead, doreadFlag, useProtocol, useSlot;
#ifdef PLAY_WITH_KEEPALIVE      
    int opt;
#endif    
    float d;
    daveInterface * di;
    daveConnection * dc;
    _daveOSserialType fds;
    doRun=0;
    doStop=0;
    doRead=0;
    doreadFlag=0;
    useProtocol=daveProtoISOTCP;
    useSlot=2;


 fds.rfd=openSocket(102, argv[1]);
    #ifdef PLAY_WITH_KEEPALIVE
    errno=0;    
    opt=1;
   //res=setsockopt(fds.rfd, SOL_SOCKET, SO_KEEPALIVE, &opt, 4);
   //LOG3("setsockopt %s %d\n", strerror(errno),res);
    #endif
 fds.wfd=fds.rfd;

    if (fds.rfd>0) 
        { 
        di =daveNewInterface(fds,"IF1",0, daveProtoISOTCP, daveSpeed187k);
        daveSetTimeout(di,5000000);
        dc =daveNewConnection(di,2,0, 2);  // insert your rack and slot here



            if (0==daveConnectPLC(dc)) 
                {
                    printf("Connected.\n");

                res=daveReadBytes(dc,daveFlags,0,0,16,NULL);
                if (0==res)  
                { 
                        a=daveGetU32(dc);
                        b=daveGetU32(dc);
                        c=daveGetU32(dc);
                        d=daveGetFloat(dc);
                    printf("FD0: %d\n",a);
                    printf("FD4: %d\n",b);
                    printf("FD8: %d\n",c);
                    printf("FD12: %f\n",d);
                }//end 0==res

                }//end daveConnectPLC


            else 

            {
        printf("Couldn't connect to PLC.\n Please make sure you use the -2 option with a CP243 but not with CPs 343 or 443.\n");    
        //closeSocket(fds.rfd);
        //return -2;
            }

    }//end fds.rfd



    fds.rfd=openSocket(102, argv[1]);
    fds.wfd=fds.rfd;

    if (fds.rfd>0) 
        { 
        di =daveNewInterface(fds,"IF1",0, daveProtoISOTCP, daveSpeed187k);
        daveSetTimeout(di,5000000);
        dc =daveNewConnection(di,2,0, 2);  // insert your rack and slot here


            if (0==daveConnectPLC(dc)) 
                {
                    printf("Connected.\n");

                res=daveReadBytes(dc,daveDB,1,0,64,NULL);
                if (0==res) 
                { 

                    a=daveGetU16(dc);
                    printf("DB1:DW0: %d\n",a);
                    a=daveGetU16(dc);
                    printf("DB1:DW1: %d\n...\n",a);
                    a=daveGetU16At(dc,62);
                    printf("DB1:DW32: %d\n",a);


                }//end 0==res

                    return 0;

                }//end daveConnectPLC
            else 

            {
        printf("Couldn't connect to PLC.\n Please make sure you use the -2 option with a CP243 but not with CPs 343 or 443.\n");    
        closeSocket(fds.rfd);
        return -2;
            }

    }//end fds.rfd






    else 
    {
    printf("Couldn't open TCP port. \nPlease make sure a CP is connected and the IP address is ok. \n");    
        return -1;
    }    



}// end main
4

4 回答 4

1

我也是新程序员。但是想说。首先我们要区分与卡的TCP/IP连接。该函数在给定的端口/服务 (102 ISO_TCP) 中连接到远程 IP 地址。当接下来调用该函数时,它将初始化用于连接 PLC 的特定接口。在此之后,该函数尝试在给定的 MPI 地址上打开连接,非常重要的是,给定的机架和插槽。如果此函数返回值 0,它将调用该函数连接到 PLC。此时,它建立了以太网连接,以及 PLC 连接。现在您可以使用库中的所有功能来读取或写入数据、停止或运行 PLC 等等。ethernetISO_TCPopenSocket()daveNewInterface()daveNewConnection()daveConnectPLC()libnodave

在实际简化的 TCP_ISO 代码中,没有断开适配器或关闭与 PLC 的连接的函数,在您的代码中有closeSocket()函数和返回 -2 的函数。查找代码在哪一行中断,例如在每个函数之后引入一个日志以查看返回值。

于 2012-06-06T22:27:32.230 回答
1

我有一个循环尝试连接 3 次,如果失败则正常退出您可以编写一些其他代码来首先检查连接是否已启动以及 PLC 是否已启动。通常,如果您尝试连接到无法解析的 IP 地址;它会挂在那里并占用资源......

于 2011-09-28T15:10:25.510 回答
1

您必须检查 daveReadBytes 函数的返回值。如果它不为零,则表示出现问题,您可以使用 daveStrerror 函数获取正确的错误消息:

printf ("error: %s\n", daveStrerror(res));

之后,由您决定是简单地重试读取还是断开连接(使用 closeSocket(...)),然后从头开始创建新连接。检查文档,了解有哪些错误代码。有些错误不能通过重试来解决(例如,因为您尝试读取一个不存在的数据块)。

于 2011-08-16T06:52:31.810 回答
0

用于检测通信丢失的所有信息都在文档中。

于 2011-08-15T12:30:01.010 回答