You are on page 1of 14

See

discussions, stats, and author profiles for this publication at: https://www.researchgate.net/publication/262198350

CoDeSys and Ethernet communication:The


concept of Sockets and basic Function Blocks
for communication over...

Article · May 2014

CITATION READS

1 8,299

1 author:

Wojciech Gomolka
Festo France
14 PUBLICATIONS 11 CITATIONS

SEE PROFILE

All content following this page was uploaded by Wojciech Gomolka on 12 May 2014.

The user has requested enhancement of the downloaded file.


GOMOLKA Wojciech
FESTO France
8, rue du Clos de St.Catherine
94363 Bry sur Marne
wojciech.gomolka@fr.festo.com

CoDeSys® v.2.3.9

Library SysLibSockets.lib

The concept of Sockets


and basic Function Blocks for communication over Ethernet

Part 1
UPD Client/Server

1
Introduction:
Basic Function Blocks for communication over Ethernet

In automation applications, there are four general use Function Blocks for communication over Ethernet
network.

1. UDP Server
2. UDP Client
For connectionless communication over Ethernet under UDP protocol

3. TCP Server
4. TCP Client
For connection oriented communication over Ethernet under TCP protocol

These Function Blocks are based on the SOCKET concept, so in this notice, we will describe some basic
elements of the socket implementation and its first application to communicate under simple,
connectionless Ethernet protocol: UDP.

We present a simple application UDP Client/Server made under CoDeSys ® and which uses some FB’s
provided by CoDeSys library: SysLibSockets.

2
1. Basic concepts of Client and Server programming
The theory and practice of Client Server systems based on the concept of Ethernet socket is very broad.
Nevertheless there are some general rules and basic steps for Client/Server connections which will be
discussed in this chapter.
For more information, you can go see different dedicated sources.

1.1 Sockets
The basic building block for communication is the socket.
A socket is an endpoint of communication via which an application (process) can send and receive data.
Each socket in use has a type and an associated process.
A socket exists as long as the associated process (application) maintains an open link to the socket.

When a process creates a socket (e.g. with socket() C-function or SysSockCreate() for CoDeSys), some
specifying parameters must be used:
a) Socket domain (address family)
b) Socket type
c) Socket supported protocols

These parameters define the socket application and how it interoperates with other socket applications.

Tab.1.1-1 Socket creation


C CoDeSys
int socket(int domain, diSocketHandle :=
int type, SysSockCreate(diAddressFamily,
int protocol); diType,
diProtocol);

1.1.1 Socket domain (address family)

The parameter Socket domain (address family) determines the format of the address structure to
use on socket functions and supported protocols for data transportation from one application to
another.

Examples of Address Family (proposed by CoDeSys)


SOCKET_AF_UNSPEC:INT:= 0; (* unspecified *)
SOCKET_AF_LOCAL:INT:= 1; (* local to host (pipes, portals) *)
SOCKET_AF_INET:INT:=2; (* internet network: protocols UDP, TCP, etc. *)
SOCKET_AF_IMPLINK:INT:=3; (* arpanet imp addresses *)
SOCKET_AF_PUP:INT:=4; (* pup protocols: e.g. BSP *)
SOCKET_AF_CHAOS:INT:=5; (* mit CHAOS protocols *)
SOCKET_AF_NS:INT:=6; (* XEROX NS protocols *)
SOCKET_AF_ISO:INT:=7; (* ISO protocols *)
SOCKET_AF_ECMA:INT:=8; (* european computer manufacturers *)
SOCKET_AF_DATAKIT:INT:=9; (* datakit protocols *)
SOCKET_AF_CCITT:INT:=10; (* CCITT protocols, X.25 etc *)
SOCKET_AF_SNA:INT:=11; (* IBM SNA *)
SOCKET_AF_DECnet:INT:=12; (* DECnet *)
...

3
For socket applications that use Internet protocols, Address family is described by global constant
AF_INET (SOCKET_AF_INET := 2 for CoDeSys).

Addresses for AF_INET sockets are IP addresses and port number and address structure is
described by basic structure sockaddr

Socket address structure : C/C++ Socket address structure : CoDeSys


struct sockaddr_in { { TYPE SOCKADDRESS :
short sin_family; STRUCT
u_short sin_port; sin_family: INT;
struct in_addr sin_addr; sin_port: UINT;
char sin_zero[8]; sin_addr: UDINT;
}; sin_zero: ARRAY [0..7] OF SINT;
END_STRUCT
(Note : _in for Internet) END_TYPE

Address structure fields:


sin_family : This field contains the address family, which is always AF_INET
when TCP or UDP is used.
sin_port : This field contains the port number
sin_addr : This field contains the Internet (IP) address
sin_zero : This field is reserved; set this field to hexadecimals zeros

1.1.2 Socket type:


Socket type determines the desired form of communication for the socket.
Two types of sockets are currently available and applied by PLC users:
- SOCK_STREAM: stream socket for the bi-directional, connection-oriented, reliable and
sequenced communication with unduplicated flow of data (TCP connection oriented,
guaranteed delivery)
- SOCK_DGRAM: datagram socket, for connectionless communication, which supports bi-
directional flow of data which is not promised to be sequenced, reliable, or unduplicated (UDP,
datagram based communication).

Normally, applications are presumed to communicate only between sockets of the same type.

1.1.3 Socket supported protocols:


The parameter Socket Supported Protocols determines the protocol that the socket uses for
network communication and data transportation from one application to another.

Examples of protocols proposed (supported) by CoDeSys sockets:


SOCKET_IPPROTO_IP: DINT:=0; (* dummy for IP protocols *)
SOCKET_IPPROTO_ICMP:DINT:=1; (* control message protocol *)
SOCKET_IPPROTO_IGMP: DINT:=2; (* group management protocol *)
SOCKET_IPPROTO_TCP: DINT:=6; (* TCP protocol *)
SOCKET_IPPROTO_PUP: DINT:=12; (* pup *)
SOCKET_IPPROTO_UDP: DINT:=17; (* UDP : user datagram protocol *)
SOCKET_IPPROTO_RAW: DINT:=255; (* raw IP packet *)

Note:
When Internet socket is created, the parameter “supported protocols” is set to 0 (default value)

4
1.1.4 Socket descriptor

When socket is created, the function returns the socket identifier: socket descriptor.
This descriptor is used as input parameter in other Socket oriented functions.

Note:
Depending OS, if socket creation was incorrect, a special constant INVALID_SOCKET (or SOCKET_INVALID) is
assigned to the socket descriptor.

E.g. CoDeSys :
SOCKET_INVALID: DINT := -1;

Example 1: Socket creation

C/C++
int my_socket;

/* TCP socket , connection oriented */


my_socket = socket(AF_INET, SOCK_STREAM,0);
if(my_socket == INVALID_SOCKET)
{
perror(“socket()”);
exit(errno);
}

CoDeSys
VAR
xSocketIsOpen: BOOL; (* bit info : Socket is open *)
diSocketHandle: DINT; (* descriptor of open Socket *)
diErrCode: DINT; (* this FB Error code *)
diAddressFamily: DINT := SOCKET_AF_INET;(* internet: UDP, TCP, ..*)
diType: DINT := SOCKET_DGRAM; (* connectionless socket *)
diProtocol: DINT := SOCKET_IPPROTO_UDP;(* User Datagram Protocol *)
END_VAR

(* code for connectionless UDP socket *)


diSocketHandle := SysSockCreate(diAddressFamily, diType, diProtocol);
IF diSocketHandle <> SOCKET_INVALID THEN
xSocketIsOpen := TRUE;
diErrCode := 0;
ELSE
xSocketIsOpen := FALSE;
diErrCode := 1;(* Err Code 1 : Open Socket not correct *)
END_IF;

IMPORTANT:
Don’t forget tests of the result for socket creation: your socket must be created correctly !!

5
1.1.5 How do sockets work?

Sockets are commonly used for client/server model of communication.


Typically, client application is placed on one machine, with the server application on other
machines.
In this scheme, client applications connect to the server, request services from a server application,
exchange information, and then disconnect.

The client and server communication model requires a well-known set of conventions before service
may be accepted and rendered. This set of conventions comprises connection modes and set of
protocols which must be implemented at both ends of a connection (sockets).

Connections and protocols provided by Client/Server sockets can be


- connection-oriented, or
- connectionless

Connection-oriented communication implies that a connection is established, and a dialog between


the programs will follow.
The server application (the program that provides the service) creates the socket which is enabled
to accept incoming connection requests.
The client of the service (the client program) must request the service of the server program. The
client does this by connecting to the distinct entry point (IP address, port) that the server program
has designated.
It is similar to dialling a telephone number (an entry point, identifier) and making a connection with
another party that is offering a service.
The receiver of the call (the server) verifies if it is able to answer correctly and when it accepts the
connection demand, the connection is established.
The connection remains active as long as both parties require it.
For AF_INET socket address family, this kind of communications is supported by TCP protocol.

Connectionless communication implies that no connection is established over which a dialog or


data transfer can take place. Instead, the server program designates an entry point (IP address,
port) where the client can send its requests.
There is no active, real time connection in which data is exchanged.
Like a post office box; if you send a letter to a post office box, you cannot be absolutely sure the
receiver got the letter. You may need to wait for a response to your letter.
For AF_INET socket address family, this kind of communications is supported by UDP protocol.

In both cases, the socket on the server process waits for requests from a client.
To do this, each server has at least to create a socket and to establish (binds) an address that
clients can use to find the server. When the address is established, the server waits for clients to
request a service.
The client-to-server data exchange takes place when:
o a client connected to the server through a socket,
o the server performs the client's request, and
o it sends the reply back to the client.
The server has to take care for closing the connection when client has closed its appropriate
connection.

6
1.1.6 How to build a UDP Client/Server socket application

The following figure illustrates the relationship between the Server and Client application in a
connectionless design.

Each step of the diagram needs the usage of specific socket functions.
Some details on the use of a particular function will be presented in next chapters.
More information could be found in respective technical documentation, e.g. online help for
operating systems.

Connectionless server uses the following sequence of function calls:

1. The socket creation function returns a socket descriptor. The INET (Internet Protocol)
address family with the UDP transport (SOCK_DGRAM) will be used for this socket.
2. After the socket descriptor is created, a bind() function establishes a unique entry point
(IP address and port) for the socket that clients can use to communicate with the server..
3. The server uses the RecvFrom() function to receive data (client request).
4. The SendTo() function is used to send data (server response) to the client.
5. The Close() function closes any open socket and destroys corresponding descriptors.

Connectionless client uses the same sequence of function calls, excepted step 3 where it uses the
SendTo() function to send (firstly) the data (request) to the server, and step 4 where RecvFrom()
function is used to receive the data back (response) from the server.

Note:
Binding is optional for Client. It can use a default port to communicate with Server.
But bind() is mandatory for the Server.

7
1.1.7 How to build a TCP Client/Server socket application

The following figure illustrates the relationship between the Server and Client application in a
connection oriented protocol design.

Connection oriented server uses the following sequence of function calls:


1. The socket creation function returns a socket descriptor. The INET (Internet Protocol)
address family with the TCP transport (SOCK_STREAM) will be used for this socket.
2. After the socket descriptor is created, a bind() function establishes a unique entry point
(IP address and port) for the socket that clients can use to communicate with the server.
3. At listening step, Listen() function is called to accept incoming client connections.
4. Function Accept() is used to accept an incoming connection request.
NB. The Accept() call will block indefinitely waiting for the incoming connection to arrive.
The Select() function allows the process to wait for an event to occur and to wake up the
process when the event occurs.
5. The server uses the Recv() function to receive data (client request).
6. The Send() function is used to send data (server response) to the client.
7. The Close() function closes any open socket descriptors when client has closed its
connection or connection was lost.

Connection oriented client doesn’t use function calls for Listen() and Accept(). At step 3 it uses the
Connect() function to establish a connection to the server.

8
1.2 Sockets and Client/Server applications: Résumé
Then, what socket function to use, when and in what order?

UDP Client:
C/C++ CoDeSys
socket() SysSockCreate()
bind() SysSockBind()
sendto() SysSockSendTo()
recvfrom() SysSockRecvFrom()
close() SysSockClose()

UDP Server:
C/C++ CoDeSys
socket() SysSockCreate()
bind() SysSockBind()
recvfrom() SysSockRecvFrom()
sendto() SysSockSendTo()
close() SysSockClose()

Note:
- For connectionless communication, the order of sento() and recvfrom() is important in Client or
Server application,
- As there is connectionless communication, in the final application with UDP Server you must
include some routines for detecting a disconnection of the Client; e.g. by sending of the special
character by Client just before disconnection.

TCP Client:
C/C++ CoDeSys
socket() SysSockCreate()
connect() SysSockConnect()
send() SysSockSend()
recv() SysSockRecv()
close() SysSockClose()

TCP Server:
C/C++ CoDeSys
socket() SysSockCreate()
bind() SysSockBind()
listen() SysSockListen()
accept() SysSockAccept()
send() SysSockSend()
recv() SysSockRecv()
close() SysSockClose()

Note:
- For connection oriented communication, the order of send() and recv() functions does not
matter. You can call one before the other or vice versa. They are also optional.

9
1.3 PLC application: Blocking/non blocking mode of sockets
The socket is basically created in the blocking mode. Some socket function calls are blocking.
This may cause trouble in PLC application because the program will stop on function call and wait
for the end.

By default, the blocking call of socket function will happen for the following CoDeSys functions:
- SysSockRecv(), SysSockSend(),
- SysSockRecvFrom(), SysSockSendTo(),
- SysSockConnect(), SysSockAccept(),
- SysSockClose();

Also, for the sequence:


SysSockRecvFrom();
SysSockSendTo();
the program will not be able to send if it does not receive anything.

There are different ways to solve this problem in PLC application:


- Use one task for PLC control and one separate task for socket handling
- Change socket mode to Non blocking mode via function SysSockIoctl()
- Use SysSockSelect() function

The second method is the simplest way to have non blocking mode of the socket behaviour.
CoDeSys library, SysLibSocket.lib provides the function of the type DINT:
SysSockIoctl(diSocket, diCommand, piParameter)
Where:
diSocket : DINT; is the descriptor of the socket, returned by SysSockCreate
diCommand : DINT; the command (with corresponding parameters) to apply on the socket
piParameter : DWORD; pointer to the command parameter

If you want to put the socket into non blocking mode, you must use a global constant (defined in
the library) which is recommended as diCommand in the SysSockIoctl call:
SOCKET_FIONBIO : DINT := 2;
And piParameter is a pointer to a variable which has to be set to value unequal zero if the socket
must be in non blocking mode.

Also, the following call could be used to put a socket into non blocking mode:

diNoBlock: DINT := 1;
SysSockIoctl(diSocket, SOCKET_FIONBIO, ADR(diNoBlock));

Very IMPORTANT NOTE:


SysSockIoctl() does not change the mode for SysSockConnect function.
This function will always work in blocking mode.

10
2. CoDeSys Basic Function Blocks for communication on Ethernet

2.1 CoDeSys FB : UDP Server


The Function Block UDPServer gives a possibility of the UDP Server functionality in Ethernet
dialogue with any UDP Client.

After reception of UDP message sent by a Client, the Server may respond to this client.
By setting the variable xSendAnswer a message can be transmitted to the client with coordinates described
by output variables strLastSenderAddr and udiSenderPort.
After execution, the variable xSendAnswer will be reset by Function Block.
IMPORTANT: Server waits for first message from Client. And if diRcvPacketCount is > 0, it is able to answer.

Tab. 2.1-1 FB UDPServer : Input variables


Type Description
EN BOOL Enable FB, if TRUE this FB will be evaluated completely normally
iLocalPort INT Local Ethernet port assigned for the Server
diMaxDataSize DINT Max size of data to transmit, if size >1472 or 0, default values are used
(1472 bytes due to the UDP protocol specification)
ptReceiveBuffer POINTER Points to a buffer (ARRAY OF BYTE) where received data should be stored
TO BYTE
diReceiveBufferSize DINT Specifies the length of the buffer (in bytes)
ptSendBuffer POINTER Points to a buffer (ARRAY OF BYTE) where transmit (send) data should be
TO BYTE stored
diNbBytesToSend DINT Specifies the number of data (bytes) to send

Tab.2.1-2 FB UDPServer : Output variables


Type Description
ENO BOOL TRUE if FB enabled and is evaluated completely
xSocketIsOpen BOOL TRUE if socket is correctly open
diSocketHandle DINT The socket file descriptor
diNbRcvBytes DINT The number of received bytes (by SysSockReceiveFrom)
strLastSenderAddr STRING IP address of the last client which sent a UDP message
udiSenderPort UDINT Ethernet port of the last client
diErrCode DINT Error code
iPhase INT Nb of internal step of FB execution (for test purposes)

Tab.2.1-3 FB UDPServer : IN_OUT variables


Type Description
xOpenSocket BOOL IF TRUE the Socket is open; If FALSE socket is closed automatically
xSendAnswer BOOL If TRUE the message with answer can be transmitted to the client.
After execution, the FB will reset this variable
diRcvPacketCount DINT Number of received UDP telegrams

11
2.2 UDP Client
The Function Block UDPClient gives a possibility to connect the application to a UDP Server.
strRemoteIPaddr is the IP address of the Server.
iRemotePort defines the communication port for the Server.
iLocalPort defines the local communication port for the FB UDPClient.

By setting the variable xSendStart a message (e.g. with request) can be transmitted to the server.
Coordinates of the Server are described by strRemoteIPaddr and iRemotePort variables.
After execution, the Function Block will reset this variable.
Length of messages is defined by diNbBytesToSend and limited to value defined by diMaxDataSize.
Maximal accepted value is 1472 Bytes due to the UDP protocol specification.

If UDPClient receives any message (e.g. from Server), coordinates of the sender are given by Output
variables:
- strLastSenderAddr : for IP address of the sender
- udiSenderPort : for the communication port of the Sender

The UDPClient can continue the dialogue in two ways:


- as Client and send message via xSendStart command
- as Server and send answer to the last sender via xSendAnswer command

In the second case, coordinates of the receiver are described by strLastSenderAddr and udiSenderPort.
After transmission, the Function Block will reset xSendAnswer.
Length of the answer messages is defined by diNbBytesToSend.

Tab. 2.2-1 FB UDPClient : Input variables

Type Description
EN BOOL Enable FB, if TRUE this FB will be evaluated completely normally
strRemoteIPaddr STRING IP address of the remote Server
udiRemotePortr DINT Ethernet port of Remote Server
iLocalPort INT Local, assigned Ethernet port
diMaxDataSize DINT Max size of data to transmit, if size >1472 or =0, default values are used
(1472 bytes due to the UDP protocol specification)
ptReceiveBuffer POINTER Points to a buffer (ARRAY OF BYTE) where received data should be stored
TO BYTE
diReceiveBufferSize DINT Specifies the length of the buffer (in bytes)
ptSendBuffer POINTER Points to a buffer (ARRAY OF BYTE) where transmit (send) data should be
TO BYTE stored
diNbBytesToSend DINT Specifies the number of data (bytes) to send

12
Tab 2.2-2 FB UDPClient : Output variables

Type Description
ENO BOOL TRUE if FB enabled and is evaluated completely
xSocketIsOpen BOOL TRUE if socket is correctly open
diSocketHandle DINT The socket file descriptor
diNbRcvBytes DINT The number of received bytes (by SysSockReceiveFrom)
strLastSenderAddr STRING IP address of the last sender which sent a UDP message
udiSenderPort UDINT Ethernet port of the last sender
diErrCode DINT Error code
iPhase INT Nb of internal step of FB execution (for test purposes)

Tab.2-2-3 FB UDPClient : IN_OUT variables


Type Description
xOpenSocket BOOL IF TRUE the Socket is open; If FALSE socket is closed automatically
xSendStart BOOL If TRUE message can be transmitted to the server described by
strRemoteIPaddr.
After execution, the FB will reset this variable
xSendAnswer BOOL If TRUE the message with answer can be transmitted to the last sender
described by strLastSenderAddr,
After execution, the FB will reset this variable
diRcvPacketCount DINT Number of received UDP telegrams

NOTE:

For the complete source code of the CoDeSys project and described POU’s: please
contact the author of this notice.

13

View publication stats

You might also like