• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 475
  • Last Modified:

Regex TCP/IP break-out box

Hi all,
I have a device sending a string pattern every half second. I am using TCP/IP to connect to it and read info.

The format goes as this:
<STX><SIGN><NUM(7)><STATUS><ETX>

STX: Start of transmission character (ASCII 02).
ETX: End of transmission character (ASCII 03).
SIGN: The sign of reading (space for positive, dash (-) for negative).
NUM: A 7 character string containing the number including the decimal point.
STATUS: A 1 character provifing info on the nature of the number

So when I connect to my device, it sends the info like this:

<STX><SIGN><NUM(7)><STATUS><ETX><STX><SIGN><NUM(7)><STATUS><ETX><STX><SIGN><NUM(7)><STATUS><ETX><STX><SIGN><NUM(7)><STATUS><ETX><STX><SIGN><NUM(7)><STATUS><ETX>...etc...

I only need to be displaying in realtime on a computer screen. What is the best way to do this? The string never ends, unless I close the port of course.

Thanks
0
vortex350
Asked:
vortex350
  • 4
  • 3
1 Solution
 
vsosuCommented:
If it is a web application, you can show it as marquee.
0
 
vortex350Author Commented:
It is not a web app. It is a winforms app. I have a textbox to refresh every second or so to read the info as it is extracted. My question has more to do with how to perform that extraction. And I need to display one info at a time.

The info being the pattern I described earlier.

Thanks
0
 
Todd GerbertIT ConsultantCommented:
I would create a seperate class to do this reading, you could pass in the Tcp socket to it's constructor, then have it start a loop on another thread and have it raise events as it decodes data.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
vortex350Author Commented:
That sounds good. Could you give me a code sample for what you are talking about?

Thanks
0
 
Todd GerbertIT ConsultantCommented:
This is a pretty rough mock-up, needs quite a bit of refinement, my goal really is just to demonstrate a concept not give you bug-free code. ;)
Using a class like the one below would allow you to simply handle the DataReceived event in your application...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;

namespace WindowsFormsApplication1
{
	public class DataDecoder
	{
		private bool disposed = false;
		Socket socket;
		Thread decodingThread;
		private ManualResetEvent workerStopSignal = new ManualResetEvent(false);

		private const byte STX = 0x02;
		private const byte ETX = 0x03;

		public delegate void DataDecodedEventHandler(object sender, string DecodedData);
		public event DataDecodedEventHandler DataDecoded;

		public DataDecoder(Socket ReceivingSocket)
		{
			if (!ReceivingSocket.Connected)
				throw new ArgumentException("Socket must be connected prior to instantiating DataDecoder.", "ReceivingSocket");
			socket = ReceivingSocket;
		}

		public void Start()
		{
			workerStopSignal.Reset();
			decodingThread = new Thread(DecodingThreadProc);
			decodingThread.IsBackground = true;
			decodingThread.Start();
		}

		public void Stop()
		{
			workerStopSignal.Set();
			decodingThread.Join();
		}

		protected virtual void OnDataDecoded(string DecodedData)
		{
			if (DataDecoded != null)
				DataDecoded(this, DecodedData);
		}

		private void DecodingThreadProc()
		{
			byte[] buffer = new byte[1024];
			bool txStarted = false;
			int bytesRead;
			StringBuilder decodedData = new StringBuilder();

			while (!workerStopSignal.WaitOne(0))
			{
				bytesRead = socket.Receive(buffer);
				for (int i = 0; i < bytesRead; i++)
				{
					if (txStarted)
					{
						if (buffer[i] == ETX)
						{
							txStarted = false;
							OnDataDecoded(decodedData.ToString());
							decodedData.Remove(0, decodedData.Length);
						}
						else
							decodedData.Append(buffer[i]);
					}
					else
						if (buffer[i] == STX)
							txStarted = true;
				}
			}
		}
	}
}

Open in new window

0
 
vortex350Author Commented:
Ok, now I am trying to understand how to get the data back from the class, how do I read the raised events as the data is decoded?

Let's say I instantiate the class on an event such as loading the form once the socket is connected.

DataDecoder dataDecode = new DataDecoder(formSocket);
dataDecode.Start();

I would send a dataDecode.Stop(); only once I close the form.

Let's say I have a textbox in my calling form, how do I refresh it's value based on the public event. Sorry if it seems like a stupid question. I am not familiar with threads because it is a vast subject I never had the courage to tackle. But after this, I will have to study it.

Thanks
0
 
Todd GerbertIT ConsultantCommented:
You would wire up the DataDecoded event of the DataDecoder object.
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;

namespace WindowsFormsApplication1
{
	public partial class Form1 : Form
	{
		private DataDecoder dataDecode;

		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			dataDecode = new DataDecoder();
			dataDecode.DataDecoded += new DataDecoder.DataDecodedEventHandler(dataDecode_DataDecoded);
			dataDecode.Start();
		}

		void dataDecode_DataDecoded(object sender, string DecodedData)
		{
			// This code block is essentially just "textBox1.Text = DecodedData",
			// but in a thread-safe manner
			if (textBox1.InvokeRequired)
			{
				textBox1.Invoke(new MethodInvoker(
					delegate()
					{
						textBox1.Text = DecodedData;
					}));
			}
		}
	}
}

Open in new window

0
 
vortex350Author Commented:
As I understand it, each time the class retrieves new information, it will be reflected in the text?

1.When I issue a dataDecode.Stop() , the program freezes as it seems to be waiting for something, I have to kill the program. Am I missing something?

2.The characters I seem to get back from my unit are numbers only, could it be an encoding option? Normally the .Append() method of the StringBuilder is supposed to append the string representation of a specified 8-bit unsigned integer when you pass it a byte which is the case here.
 I know I should probably use something like Encoding.ASCII.GetString(buffer,0,1) but don't seem to be able to implement it in the code.

Thanks for your help.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now