.NET Peer-to-Peer communication

This sample demonstrates how a .NET communication partner for PLC samples Peer-to-Peer device A or B can be realized.

.NET Peer-to-Peer communication 1:

How it works

The sample uses the includes System.Net and System.Net.Sockets to implement a UDP client (class UdpClient). While listening for incoming UDP packets in a background thread, a string can be sent to a remote device by specifying its IP address and port number and clicking the "Send" button.

For a better understanding of this article, imagine the following setup:

How to set up the PLC sample

This .NET sample may be used together with the PLC samples Peer-to-Peer device A or B. If you run the application on separate computer than the PLC runtime, you need to configure IP addresses in both applications according to the assumed specifications from above.

Setting

Type

Description

LOCAL_HOST_IP

Global constant

Needs to be set to 10.1.128.21 (IP of computer which runs PLC)

LOCAL_HOST_PORT

Global constant

Set this constant to 1001 (default value)

REMOTE_HOST_IP

Global constant

Needs to be set to 10.1.128.30 (IP of computer which runs .NET sample)

REMOTE_HOST_PORT

Global constant

Set this constant to 1002 (default value)

bSendOnceToRemote

Global variable

If set to TRUE, a UDP packet will be send to REMOTE_HOST_IP

How to set up the .NET sample

Setting

Type

Description

DEFAULTIP

Global constant

Will be used in text field "Host" as default value. Set it to 10.1.128.21.

DEFAULTDESTPORT

Global constant

Will be used in text field "Port" as default value. Set it to 1001.

DEFAULTOWNPORT

Global constant

Will be used by PLC sample in REMOTE_HOST_PORT. Set it to 1002.

DEFAULTSOURCEPORT

Global constant

Used as source port for sending out UDP packet. Not important in this sample.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
using System.Net;
using System.Net.Sockets;
using System.Threading;
 
 
namespace TcpIpServer_SampleClientUdp
{
    publicpartialclassForm1 : Form
    {
    /* ##########################################################################################     * Constants     * ########################################################################################## */privateconststring DEFAULTIP = "127.0.0.1";
    privateconstint DEFAULTDESTPORT = 1001; // Used as destination portprivateconstint DEFAULTOWNPORT = 1002; // Used for binding when listening for UDP messagesprivateconstint DEFAULTSOURCEPORT = 11000; // Only used as source port when sending UDP messages/* ##########################################################################################     * Global variables     * ########################################################################################## */privatestaticUdpClient _udpClient;
    privatestaticIPEndPoint _ipAddress; // Contains IP address as entered in text fieldprivatestaticThread _rcvThread; // Background thread used to listen for incoming UDP packetspublic Form1()
    {
        InitializeComponent();
    }
 
 
    /* ##########################################################################################     * Event handler method called when button "Send" is pressed     * ########################################################################################## */privatevoid cmd_send_Click(object sender, EventArgs e)
    {
        byte[] sendBuffer = null;
 
        /* ##########################################################################################         * Preparing UdpClient, connecting to UDP server and sending content of text field         * ########################################################################################## */try
        {
        _ipAddress = newIPEndPoint(IPAddress.Parse(txt_host.Text), Convert.ToInt32(txt_port.Text));
        _udpClient = newUdpClient(DEFAULTSOURCEPORT);
        _udpClient.Connect(_ipAddress);
        
        sendBuffer = Encoding.ASCII.GetBytes(txt_send.Text);
        _udpClient.Send(sendBuffer, sendBuffer.Length);
        
        _udpClient.Close();
        }
        catch (Exception ex)
        {
        MessageBox.Show("An unknown error occured: " + ex);
        }
    }
 
 
    /* ##########################################################################################     * Event handler method called when application starts     * ########################################################################################## */privatevoid Form1_Load(object sender, EventArgs e)
    {
        txt_host.Text = DEFAULTIP;
        txt_port.Text = DEFAULTDESTPORT.ToString();
        rtb_rcv.Enabled = false;
 
        /* ##########################################################################################         * Creating background thread which synchronously listens for incoming UDP packets         * ########################################################################################## */
        _rcvThread = newThread(rcvThreadMethod);
        _rcvThread.Start();
    }
 
 
    /* ##########################################################################################     * Delegate, so that background thread may write into text field on GUI     * ########################################################################################## */publicdelegatevoidrcvThreadCallback(string text);
 
 
    /* ##########################################################################################     * Method called by background thread     * ########################################################################################## */privatevoid rcvThreadMethod()
    {
        /* ##########################################################################################         * Listen on any available local IP address and specified port (DEFAULTOWNPORT)         * ########################################################################################## */byte[] rcvBuffer = null;
        IPEndPoint ipEndPoint = newIPEndPoint(IPAddress.Any, DEFAULTOWNPORT);;
        UdpClient udpClient = newUdpClient(ipEndPoint);
 
        /* ##########################################################################################         * Continously start a synchronous listen for incoming UDP packets. If a packet has arrived,         * write its content to receive buffer and then into the text field. After that, start circle         * again.         * ########################################################################################## */while (true)
        {
        rcvBuffer = udpClient.Receive(ref ipEndPoint); // synchronous call
        rtb_rcv.Invoke(newrcvThreadCallback(this.AppendText), newobject[] { "\n" + DateTime.Now.ToString() + ": " + Encoding.ASCII.GetString(rcvBuffer) });
        }
    }
 
 
    /* ##########################################################################################     * Helper method for delegate     * ########################################################################################## */privatevoid AppendText(string text)
    {
        rtb_rcv.AppendText(text);
    }
 
 
    /* ##########################################################################################     * Stop background thread when application closes     * ########################################################################################## */privatevoid Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        _rcvThread.Abort();
    }
    }
}