如何向 libnodave 测试程序(简化的 testISO_TCP)添加代码以防止读取例程崩溃?

发布于 2024-11-29 17:59:39 字数 3633 浏览 1 评论 0原文

首先我要说的是,我是一名几乎没有 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

I will start by saying that I am a college student with little c++ experience. How many times have you heard that right? I am working with the test program testISO_TCP (simplified version) from the libnodave library. This program does a simple read of flag values and data blocks while it is connected to a seimens 300 PLC. The program doesn't bring up any errors per se. What I am trying to do is hopefully add some code to this program that will protect the reads from ever crashing. Let me explain a little better. Say for example I have a lot of reads implemented in the code. As of now there are only two reads. Eventually I will run this code with many more reads. Now, say that I am running the test program and for some reason I lose the connection to the PLC. I would like to have the program do one of two things: 1) Once the connection is lost, do a retry connect a certain amount of times and when it runs out of tries, exit. or 2) Somehow continue to read from the PLC until they are all done.

I hope this is enough information to get some help. I will post the code that I have been looking at for so long without any idea how to do this effectively. Thanks to all in advance.

#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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

澉约 2024-12-06 17:59:40

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

All info for detecting loss of communication is in the documentation.

心如狂蝶 2024-12-06 17:59:39

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

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

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

You have to check the return value of the daveReadBytes function.
If it is not zero, something went wrong and you can use the daveStrerror function to get a proper error message:

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

After that it's up to you to decide to either simply retry the read or disconnect (with closeSocket(...)) and then create a new connection from the beginning. Check the documentation on what errorcodes there are. Some errors can't be resolved by retrying (e.g. because you try reading a data block that doesn't exist).

太阳公公是暖光 2024-12-06 17:59:39

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

I have a loop that attempts to connect 3 times and exits gracefully if it fails
You may be able to write some other code to first check to see if the connection is up and also if the PLC is up.
Typically if you try to connect to an IP address that doesn't esond; it will hang there and tie up resources...

愁以何悠 2024-12-06 17:59:39

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

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

I am also new programmer.But want to say that. First we have to differentiate between the TCP/IP connection with the ethernet card ISO_TCP. The openSocket() function does the connection to remote IP adress in the given port/Service (102 ISO_TCP). When called next, the function daveNewInterface(), it will initialise the specific interface for doing a connection to the PLC. After this, the function daveNewConnection() tries to open a connection on a given MPI adress, and very important, the given rack and slot. If this function returns the value 0, it will call the daveConnectPLC() function to connect to the PLC. At this point it´s established a ethernet connection,and also the PLC Connection.
Now you can use all the function from the libnodave library for read or write data, stop or run the PLC and much more.

In the actually simplified TCP_ISO code there are no function to disconnect the adapter or close the connection with the PLC, in your code there is the closeSocket() function and also the function that returns -2. Find at what line the code breaks, introducing for example a log after every function to see the returns values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文