Up | Example 01 - StructuredPropertyBag | Example 02 - WinForms Controls | Example 3 - Custom User Interface | Example 04 - TCP Socket Communication | Example 05 - Simple Text Print | Example 06 - Modeless .Net Dialog | Example 07 - StopWatch | Example 08 - Product Selection Page | Example 09 - PyScripter - Eclipse Test Program | Example 10 - Access Control with custom .Net Plugin

 

  

 
Example 04 - TCP Socket Communication

This example shows how to use non-GUI .NET components.

The .NET Framework contains easy to use classes for TCP Socket communication (TcpClient and TcpListener). These components can be used in simple scenarios where synchronous (blocking) operation is acceptable. It is also possible to use the low-level Socket class both for synchronous and asynchronous communication. The asynchronous use of socket communication in .NET is not very difficult, but it can be dangerous to use it in a windowed environment without handling the multithreaded issues properly. The asynchronous mode operation is based on callbacks, and these callbacks are normally called on another thread than the primary thread for the window application. If the callback calls into code that manipulates any window control, the single threaded use of Win32 is violated. This will result in bugs that are difficult to track down and correct.

Tordivel has developed a socket communication component that ensure that all callbacks are routed to events that are called on the main thread of the application. The RawTcpMessenger component can act both as a socket communication server (listen for connections) and a socket communication client.

Here is the user interface created for demonstration purposes by the following script.

A separate test/demo program for RawTcpMessenger is also enclosed with the RawTcpMessenger profile.

# Python start script goes here
print 'Central Start'

import CLR
import CLR.System.Windows.Forms as WinForms
from CLR.System.Text import Encoding
from CLR.System.Net import Dns, IPHostEntry, IPEndPoint, IPAddress
from CLR.System.Drawing import Size, Point, ContentAlignment, Font
from CLR.System import Int32, Decimal

# Load custom assemblies
from CLR.System.Reflection import Assembly
scorpionDir = GetValue('System.ScorpionDir')
Assembly.LoadFrom(scorpionDir + r'\OverlayPanel.dll')
from CLR.Tordivel import OverlayPanel
# Custom .NET components should be placed in DotNet folder in profile path
profile = GetValue('System.Profile')
Assembly.LoadFrom(profile + r'\DotNet\RawTcpMessenger.dll')
from CLR.Tordivel import RawTcpMessenger

class ResultPanelOverlay(OverlayPanel):
  def __init__(self,nativeParentHandleAsInt32):

    self.Dock = WinForms.DockStyle.Fill

    # Show Debug Trace from .NET Code
    #self.ShowTrace = 1

    # Create the errorProvider control
    self.errorProvider = WinForms.ErrorProvider()
    self.errorProvider.BlinkStyle = WinForms.ErrorBlinkStyle.NeverBlink

    # Get local ip address (use first in list if many)
    hostName = Dns.GetHostName()
    iphostentry = Dns.GetHostByName(hostName)
    self.localAddress = iphostentry.AddressList[0].ToString()

    # Create the RawTcpMessenger component
    self.rawTcpMessenger = RawTcpMessenger(self)

    # Register handler for rawTcpMessenger.Receive event
    self.rawTcpMessenger.Receive += self.rawTcpMessenger_ReceiveHandler
    # Register handler for rawTcpMessenger.RemoteConnect event
    self.rawTcpMessenger.RemoteConnect += self.rawTcpMessenger_RemoteConnectHandler
    # Register handler for rawTcpMessenger.RemoteDisconnect event
    self.rawTcpMessenger.RemoteDisconnect += self.rawTcpMessenger_RemoteDisconnectHandler
    # Register handler for rawTcpMessenger.SendError event
    self.rawTcpMessenger.SendError += self.rawTcpMessenger_SendErrorHandler

    # Create the listenAddressTextBox
    self.listenAddressTextBox = WinForms.TextBox()
    self.listenAddressTextBox.Parent = self
    self.listenAddressTextBox.Size = Size(100,25)
    self.listenAddressTextBox.Location = Point(115,12)
    self.listenAddressTextBox.Text = self.localAddress
    self.listenAddressTextBox.ReadOnly = 1

    # Create the listenAddressLabel (after the listenAddressTextBox to avoid hiding)
    self.listenAddressLabel = WinForms.Label()
    self.listenAddressLabel.Parent = self
    self.listenAddressLabel.Size = Size(120,25)
    self.listenAddressLabel.Location = Point(10,10)
    self.listenAddressLabel.Text = "Listen address:"
    self.listenAddressLabel.TextAlign = ContentAlignment.MiddleLeft

    # Create the listenPortUpDown
    self.listenPortUpDown = WinForms.NumericUpDown()
    self.listenPortUpDown.Parent = self
    self.listenPortUpDown.Size = Size(80,25)
    self.listenPortUpDown.Location = Point(320,12)
    self.listenPortUpDown.Minimum = Decimal(1000)
    self.listenPortUpDown.Maximum = Decimal(100000)
    self.listenPortUpDown.ReadOnly = 1
    # Register event handler for listenPortUpDown.ValueChanged
    self.listenPortUpDown.ValueChanged += self.listenPortUpDown_ValueChangedHandler
    # Set the value after registering the value changed event handler
    self.listenPortUpDown.Value = Decimal(12345)

    # Create the listenPortLabel (after the listenPortTextBox to avoid hiding)
    self.listenPortLabel = WinForms.Label()
    self.listenPortLabel.Parent = self
    self.listenPortLabel.Size = Size(120,25)
    self.listenPortLabel.Location = Point(230,10)
    self.listenPortLabel.Text = "Listen port:"
    self.listenPortLabel.TextAlign = ContentAlignment.MiddleLeft

    # Create the destinationAddressTextBox
    self.destinationAddressTextBox = WinForms.TextBox()
    self.destinationAddressTextBox.Parent = self
    self.destinationAddressTextBox.Size = Size(100,25)
    self.destinationAddressTextBox.Location = Point(115,42)
    self.destinationAddressTextBox.Text = self.localAddress

    # Create the destinationAddressLabel (after the destinationAddressTextBox to avoid hiding)
    self.destinationAddressLabel = WinForms.Label()
    self.destinationAddressLabel.Parent = self
    self.destinationAddressLabel.Size = Size(120,25)
    self.destinationAddressLabel.Location = Point(10,40)
    self.destinationAddressLabel.Text = "Destination address:"
    self.destinationAddressLabel.TextAlign = ContentAlignment.MiddleLeft

    # Create the destinationPortUpDown
    self.destinationPortUpDown = WinForms.NumericUpDown()
    self.destinationPortUpDown.Parent = self
    self.destinationPortUpDown.Size = Size(80,25)
    self.destinationPortUpDown.Location = Point(320,42)
    self.destinationPortUpDown.Minimum = Decimal(1000)
    self.destinationPortUpDown.Maximum = Decimal(100000)
    self.destinationPortUpDown.Value = Decimal(12346)
    # Register event handler for destinationPortUpDown.ValueChanged
    self.destinationPortUpDown.ValueChanged += self.destinationPortUpDown_ValueChangedHandler

    # Create the destinationPortLabel (after the destinationPortUpDown to avoid hiding)
    self.destinationPortLabel = WinForms.Label()
    self.destinationPortLabel.Parent = self
    self.destinationPortLabel.Size = Size(120,25)
    self.destinationPortLabel.Location = Point(230,40)
    self.destinationPortLabel.Text = "Destination port:"
    self.destinationPortLabel.TextAlign = ContentAlignment.MiddleLeft

    # Create the connectCheckBox
    self.connectCheckBox = WinForms.CheckBox()
    self.connectCheckBox.Parent = self
    self.connectCheckBox.Appearance = WinForms.Appearance.Button
    self.connectCheckBox.Size = Size(60,22)
    self.connectCheckBox.Location = Point(405,42)
    self.connectCheckBox.Text = "Connect"
    self.connectCheckBox.TextAlign = ContentAlignment.MiddleCenter
    # Register event handler for connectCheckBox.Click
    self.connectCheckBox.Click += self.connectCheckBox_ClickHandler

    # Create the messageTextBox
    self.messageTextBox = WinForms.TextBox()
    self.messageTextBox.Parent = self
    self.messageTextBox.Size = Size(260,25)
    self.messageTextBox.Location = Point(70,82)
    self.messageTextBox.Text = "Hello"

    # Create the messageLabel (after the messageTextBox to avoid hiding)
    self.messageLabel = WinForms.Label()
    self.messageLabel.Parent = self
    self.messageLabel.Size = Size(100,25)
    self.messageLabel.Location = Point(10,80)
    self.messageLabel.Text = "Message:"
    self.messageLabel.TextAlign = ContentAlignment.MiddleLeft

    # Create the sendButton
    self.sendButton = WinForms.Button()
    self.sendButton.Parent = self
    self.sendButton.Size = Size(60,22)
    self.sendButton.Location = Point(340,80)
    self.sendButton.Text = "Send"
    # Register event handler for sendButton.Click
    self.sendButton.Click += self.sendButton_ClickHandler

    # Create the listbox
    self.listBox = WinForms.ListBox()
    self.listBox.Parent = self
    self.listBox.Size = Size(480,250)
    self.listBox.Location = Point(10,120)
    self.listBox.Sorted = 0


  def listenPortUpDown_ValueChangedHandler(self, sender, args):
    # Handles the listenPortUpDown ValueChanged event

    listenPort = Decimal.ToInt32(self.listenPortUpDown.Value)
    if self.rawTcpMessenger.StartListen(self.localAddress,listenPort):
      self.errorProvider.SetError(self.listenPortUpDown,"")
    else:
      self.errorProvider.SetError(self.listenPortUpDown,"Can NOT Listen")


  def destinationPortUpDown_ValueChangedHandler(self, sender, args):
    # Handles the destinationPortUpDown ValueChanged event

    self.errorProvider.SetError(self.connectCheckBox,"");
    destinationAddress = self.destinationAddressTextBox.Text
    destinationPort = Decimal.ToInt32(self.destinationPortUpDown.Value)
    self.connectCheckBox.Checked = self.rawTcpMessenger.IsConnected(destinationAddress,destinationPort)

  def connectCheckBox_ClickHandler(self, sender, args):
    # Handles the connectButton Click event

    self.errorProvider.SetError(self.connectCheckBox,"");
    destinationAddress = self.destinationAddressTextBox.Text
    destinationPort = Decimal.ToInt32(self.destinationPortUpDown.Value)
    if self.connectCheckBox.Checked:
      if self.rawTcpMessenger.IsConnected(destinationAddress,destinationPort) != 1:
        if self.rawTcpMessenger.Connect(destinationAddress,destinationPort) != 1:
          self.errorProvider.SetError(connectCheckBox,"Connect Failed")
    else:
      self.rawTcpMessenger.Disconnect(destinationAddress,destinationPort)


  def sendButton_ClickHandler(self, sender, args):
    # Handles the sendButton Click event

    destinationAddress = self.destinationAddressTextBox.Text
    destinationPort = Decimal.ToInt32(self.destinationPortUpDown.Value)
    messageText = self.messageTextBox.Text
    self.rawTcpMessenger.Send(destinationAddress,destinationPort,Encoding.ASCII.GetBytes (self.messageTextBox.Text))


  def rawTcpMessenger_ReceiveHandler(self, sender, args):
    # Handles the rawTcpMessenger Receive event

    messageText = args.senderAddress + ":" + str(args.senderPort) + " " + Encoding.ASCII.GetString (args.message,0,args.message.Length)
    self.listBox.Items.Add(messageText)


  def rawTcpMessenger_RemoteConnectHandler(self, sender, args):
    # Handles the tcpMessenger RemoteConnect event

    messageText = args.remoteAddress + ":" + str(args.remotePort) + " Connected"
    self.listBox.Items.Add(messageText)


  def rawTcpMessenger_RemoteDisconnectHandler(self, sender, args):
    # Handles the tcpMessenger RemoteDisconnect event

    messageText = args.remoteAddress + ":" + str(args.remotePort) + " Disconnected"
    self.listBox.Items.Add(messageText)


  def rawTcpMessenger_SendErrorHandler(self, sender, args):
    # Handles the tcpMessenger SendError event

    messageText = args.remoteAddress + ":" + str(args.remotePort) + " SendError: " + args.errorDescription
    self.listBox.Items.Add(messageText)


# try to close existing RawTcpMessenger
try:
  resultPanelOverlay.rawTcpMessenger.Close()
  resultPanelOverlay.Dispose()
except:
  print 'Dispose Failed'


# Create global instance of resultPanelOverlay
resultPanelOverlay = ResultPanelOverlay(GetResultPanel().handle)
 

 

Scorpion Vision Version XII : Build 646 - Date: 20170225
Scorpion Vision Software® is a registered trademark of Tordivel AS.
Copyright © 2000 - 2017 Tordivel AS.