CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum by 3S-Smart Software Solutions GmbH | A member of the CODESYS Group
Deutsche Version English version russian version 
It is currently Wed Jan 22, 2020 11:38 pm

All times are UTC+01:00




Post new topic  Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Tue Dec 04, 2012 1:04 pm 
Offline

Joined: Mon Nov 01, 2010 4:30 pm
Posts: 52
Hi,

I'm trying the TcpIp.pro example project from here
ftp://ftp2.3s-software.com/pub/Examples ... ion/TcpIp/

I need to use the TCPClient() program to connect to a TCP server.
It works OK if the server is present & listening. But if the server is not present, the task to which TCPClient() program belongs freezes really badly - in the Task Configuration, for a given period, the run counter for this task increments by 7-8 while the counter for another task with equal priority and cycle time increments by 1000 for the same period. This is if I load the project to PLCWinNT emulator.

If I load the project to a real PLC, the task freezes completely - run counter increments by 1 every 50 - 60 seconds.
As far as I can tell, the problem is in the function call
SysSockConnect(diSocket, ADR(sa), SIZEOF(sa))
which returns after a really huge period of time if there is nothing to connect to.

So my question is, what can I do to avoid this task freezing? SysSockConnect doesn't have a timeout parameter.
Is there a simple way to just check if a device is present, like ping ?

Thanks for any suggestions.


Top
   
PostPosted: Tue Dec 04, 2012 9:01 pm 
Offline

Joined: Mon Dec 27, 2010 2:35 pm
Posts: 71
That's right, by default all the calls of SysLibSockets library are blocking.

I recommend to check the OSCAT networking libray, see http://www.oscat.de, and browse the source for solution.
In the IP_CONROL FB (under the HARDWARE folder), section TC_INIT, you will see the right way to use SysSockConnect.
I think, the relevant part is:

Code:
IF plc_841 OR plc_881 THEN
   SysSockSetOption(socket,6,SOCKET_TCP_NODELAY, ADR(dint_true), SIZEOF(dint_true)); (* Set Push-Bit *)
END_IF;
SysSockIoctl(socket, SOCKET_FIONBIO, ADR(dint_true)); (* NonBlocking mode *)


And then, once you told ioctl to go to nonblocking mode, "select" might have called after SysSockConnect. (and also before read and write operations) The code used in OSCAT tries to determine if "select" is needed...

Code:
      IF c_select = FALSE THEN
         IF SysSockConnect(socket,ADR(sockaddr),SIZEOF(sockaddr)) THEN
            c_ready := TRUE; (* Connected *)
            state:= C_WAIT;
         ELSE
            (* Connect durchgeführt, aber noch nicht verbunden, dann optional mit select-abfrage weitermachen *)
            c_select := SYSLIBSOCKETS_OPTION.0; (* Bit 0 = TCP-Client - use SysSockselect *)
         END_IF;
      ELSE
         c_Timeout.tv_sec := 0;
         c_Timeout.tv_usec := 0;
         c_fdWrite.fd_count := 1;
         c_fdWrite.fd_array[0] := socket;
         IF SysSockSelect(SOCKET_FD_SETSIZE,0,ADR(c_fdWrite),0, ADR(c_Timeout)) > 0 THEN
            c_ready := TRUE; (* Connected *)
            state:= C_WAIT;
         END_IF;
      END_IF;


The other option, is to use SysLibSocketsAsync.lib, but there are some platforms where it's not available. In this case, instead of functions function blocks are called...

(I hope it's not a problem to quote from OSCAT. It's almost like a cookbook for many of us, thanks for the authors. Btw: Does someone know, what are plc_841 and plc_881 bool variables in OSCAT IP_CONTROL? And what is the difference between IP_CONTROL and IP_CONTROL2?

(This could be asked at the OSCAT forum... but once we are here...)


Top
   
PostPosted: Wed Dec 05, 2012 7:43 am 
Offline

Joined: Thu Jun 22, 2006 6:38 am
Posts: 72
Wago have a PLC called 750-881 and a programmable controler with the number 750-841.
Don't know what it has to do with the code.


Top
   
PostPosted: Wed Dec 05, 2012 2:23 pm 
Offline

Joined: Mon Nov 01, 2010 4:30 pm
Posts: 52
thanks for the reply.
I got OSCAT networking library, checked the code and tried some stuff. But this was pure guess-work, and indeed didn't work :cry:

Isn't there a simple non-blocking way to only check if there is something at given IP address?


Top
   
PostPosted: Thu Dec 06, 2012 7:55 am 
Offline

Joined: Mon Dec 27, 2010 2:35 pm
Posts: 71
The following code is non-blocking, works fine. It has to be called until xConnected or a timeout reached (a TON for example).
On your platform the SOCKET_TCP_NODELAY might not be called.

Code:
xConnected := FALSE;

IF diSocketID <=0 THEN

   saSocketAddress.sin_addr   := SysSockInetAddr(sIPAddr);
   saSocketAddress.sin_port   := SysSockHtons(uiPort);
   saSocketAddress.sin_family := SOCKET_AF_INET;

   diSocketID:=SysSockCreate(diAddressFamily := SOCKET_AF_INET,
                     diType := SOCKET_STREAM,
                     diProtocol          := 0);

   IF diSocketID = SOCKET_INVALID THEN
      RETURN;
   END_IF;

   SysSockSetOption(diSocketID, SOCKET_SOL, SOCKET_SO_SNDBUF, ADR(Settings.diMaxDataSize), SIZEOF(Settings.diMaxDataSize));
   SysSockSetOption(diSocketID, SOCKET_SOL, SOCKET_SO_RCVBUF, ADR(Settings.diMaxDataSize), SIZEOF(Settings.diMaxDataSize));
   SysSockSetOption(diSocketID, SOCKET_SOL, SOCKET_SO_LINGER, ADR(Settings.lOptLinger), SIZEOF(Settings.lOptLinger));
   SysSockSetOption(diSocketID, SOCKET_IPPROTO_TCP, SOCKET_TCP_NODELAY, ADR(Settings.xOptNoDelay),    SIZEOF(Settings.xOptNoDelay));
   SysSockIoctl(diSocketID, SOCKET_FIONBIO, ADR(Settings.diNonBlocking));
   xSelect := FALSE;
END_IF

IF NOT xSelect THEN
   IF SysSockConnect(diSocketID, ADR(saSocketAddress), SIZEOF(saSocketAddress)) THEN
      xConnected := TRUE;
   ELSE
      xSelect := Settings.xUseSelect;
   END_IF
ELSE
   fdWrite.fd_count := 1;
   fdWrite.fd_array[0] := diSocketID;
   IF SysSockSelect(SOCKET_FD_SETSIZE,0,ADR(fdWrite),0, ADR(Settings.tvTimeout)) > 0 THEN
      xConnected := TRUE;
   END_IF;
END_IF


Top
   
PostPosted: Mon Nov 09, 2015 1:00 pm 
Offline

Joined: Fri Nov 06, 2015 1:14 pm
Posts: 3
Hello, the ftp link seems broke. Can you guys help me with a functional example of socket TCP_IP communication on SysLibSocketsAsync.lib library? Thank you.


Top
   
PostPosted: Mon Jan 29, 2018 8:39 am 
Offline

Joined: Wed Oct 25, 2017 10:25 am
Posts: 14
Strucc wrote:
The following code is non-blocking, works fine. It has to be called until xConnected or a timeout reached (a TON for example).
On your platform the SOCKET_TCP_NODELAY might not be called.

Code:
xConnected := FALSE;

IF diSocketID <=0 THEN

   saSocketAddress.sin_addr   := SysSockInetAddr(sIPAddr);
   saSocketAddress.sin_port   := SysSockHtons(uiPort);
   saSocketAddress.sin_family := SOCKET_AF_INET;

   diSocketID:=SysSockCreate(diAddressFamily := SOCKET_AF_INET,
                     diType := SOCKET_STREAM,
                     diProtocol          := 0);

   IF diSocketID = SOCKET_INVALID THEN
      RETURN;
   END_IF;

   SysSockSetOption(diSocketID, SOCKET_SOL, SOCKET_SO_SNDBUF, ADR(Settings.diMaxDataSize), SIZEOF(Settings.diMaxDataSize));
   SysSockSetOption(diSocketID, SOCKET_SOL, SOCKET_SO_RCVBUF, ADR(Settings.diMaxDataSize), SIZEOF(Settings.diMaxDataSize));
   SysSockSetOption(diSocketID, SOCKET_SOL, SOCKET_SO_LINGER, ADR(Settings.lOptLinger), SIZEOF(Settings.lOptLinger));
   SysSockSetOption(diSocketID, SOCKET_IPPROTO_TCP, SOCKET_TCP_NODELAY, ADR(Settings.xOptNoDelay),    SIZEOF(Settings.xOptNoDelay));
   SysSockIoctl(diSocketID, SOCKET_FIONBIO, ADR(Settings.diNonBlocking));
   xSelect := FALSE;
END_IF

IF NOT xSelect THEN
   IF SysSockConnect(diSocketID, ADR(saSocketAddress), SIZEOF(saSocketAddress)) THEN
      xConnected := TRUE;
   ELSE
      xSelect := Settings.xUseSelect;
   END_IF
ELSE
   fdWrite.fd_count := 1;
   fdWrite.fd_array[0] := diSocketID;
   IF SysSockSelect(SOCKET_FD_SETSIZE,0,ADR(fdWrite),0, ADR(Settings.tvTimeout)) > 0 THEN
      xConnected := TRUE;
   END_IF;
END_IF



Hi, I'm working on a similar project. I have a raspberry in which I need to run a TCP server where I will receive messages from clients by sockets. I can not get it to work properly, have you managed to get it to work properly? Do you have more information on the server or a example project?

Thank you very much.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 7 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited