Document not found! Please try again

The concept of Sockets and basic Function Blocks for ...

139 downloads 29227 Views 433KB Size Report
We present a simple application UDP Client/Server made under CoDeSys ... For more information, you can go see different dedicated sources. .... Like a post office box; if you send a letter to a post office box, you cannot be absolutely sure the.
GOMOLKA Wojciech FESTO France 8, rue du Clos de St.Catherine 94363 Bry sur Marne [email protected]

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 int socket(int domain, int type, int protocol);

CoDeSys diSocketHandle := SysSockCreate(diAddressFamily, 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++ struct sockaddr_in { { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; (Note : _in for Internet)

Socket address structure : CoDeSys TYPE SOCKADDRESS : STRUCT sin_family: sin_port: sin_addr: sin_zero: END_STRUCT END_TYPE

INT; UINT; UDINT; ARRAY [0..7] OF SINT;

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 bidirectional 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: diSocketHandle: diErrCode: diAddressFamily: diType: diProtocol: END_VAR

BOOL; (* bit info : Socket is open *) DINT; (* descriptor of open Socket *) DINT; (* this FB Error code *) DINT := SOCKET_AF_INET;(* internet: UDP, TCP, ..*) DINT := SOCKET_DGRAM; (* connectionless socket *) DINT := SOCKET_IPPROTO_UDP;(* User Datagram Protocol *)

(* 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++ socket() bind() sendto() recvfrom() close()

CoDeSys SysSockCreate() SysSockBind() SysSockSendTo() SysSockRecvFrom() SysSockClose()

C/C++ socket() bind() recvfrom() sendto() close()

CoDeSys SysSockCreate() SysSockBind() SysSockRecvFrom() SysSockSendTo() SysSockClose()

UDP Server:

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++ socket() connect() send() recv() close()

CoDeSys SysSockCreate() SysSockConnect() SysSockSend() SysSockRecv() SysSockClose()

C/C++ socket() bind() listen() accept() send() recv() close()

CoDeSys SysSockCreate() SysSockBind() SysSockListen() SysSockAccept() SysSockSend() SysSockRecv() SysSockClose()

TCP Server:

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: for IP address of the sender - strLastSenderAddr : : for the communication port of the Sender - udiSenderPort 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

EN strRemoteIPaddr udiRemotePortr iLocalPort diMaxDataSize ptReceiveBuffer diReceiveBufferSize ptSendBuffer diNbBytesToSend

Type BOOL STRING DINT INT DINT POINTER TO BYTE DINT POINTER TO BYTE DINT

Description Enable FB, if TRUE this FB will be evaluated completely normally IP address of the remote Server Ethernet port of Remote Server Local, assigned Ethernet port Max size of data to transmit, if size >1472 or =0, default values are used (1472 bytes due to the UDP protocol specification) Points to a buffer (ARRAY OF BYTE) where received data should be stored Specifies the length of the buffer (in bytes) Points to a buffer (ARRAY OF BYTE) where transmit (send) data should be stored Specifies the number of data (bytes) to send

12

Tab 2.2-2

FB UDPClient : Output variables

ENO xSocketIsOpen diSocketHandle diNbRcvBytes strLastSenderAddr udiSenderPort diErrCode iPhase

Type BOOL BOOL DINT DINT STRING UDINT DINT INT

Description TRUE if FB enabled and is evaluated completely TRUE if socket is correctly open The socket file descriptor The number of received bytes (by SysSockReceiveFrom) IP address of the last sender which sent a UDP message Ethernet port of the last sender Error code 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