Files
qController/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs
T
jwetzell 9899a6d33e BIG TCP Overhaul and passcode start
- Switch to Serilog for console logging
- TCPSender is now persistent (let's hope) so can be used with passcode protected workspaces
- UDP connection works with passcodes just can't timeout
- Passcode prompt is automatic for workspaces that are password protected
2020-06-05 23:53:16 -05:00

153 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using Serilog;
namespace SharpOSC
{
public class MessageEventArgs : EventArgs
{
public OscMessage Message
{
get;
set;
}
}
public class TCPSender
{
public int Port
{
get { return _port; }
}
int _port;
public string Address
{
get { return _address; }
}
public delegate void MessageReceivedHandler(object source, MessageEventArgs args);
public event MessageReceivedHandler MessageReceived;
string _address;
TcpClient client;
byte END = 0xc0;
byte ESC = 0xdb;
byte ESC_END = 0xDC;
byte ESC_ESC = 0xDD;
public TCPSender(string address, int port)
{
_port = port;
_address = address;
}
public void Connect()
{
client = new TcpClient(Address, Port);
Log.Debug($"TCPSender - connect called for <{Address}:{Port}>");
Thread receivingThread = new Thread(ReceiveLoop);
receivingThread.Start();
}
public void Send(byte[] message)
{
byte[] slipData = SlipEncode(message);
NetworkStream netStream = client.GetStream();
netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length);
}
public void Send(OscPacket packet)
{
byte[] data = packet.GetBytes();
Send(data);
}
public void ReceiveLoop()
{
while (client.Connected)
{
Receive();
}
Log.Debug("TCPSender - Receive Loop has exited for some reason");
}
public void Receive()
{
Random random = new Random();
int num = random.Next(1000);
NetworkStream netStream = client.GetStream();
try
{
netStream.ReadTimeout = 250;
List<byte> responseData = new List<byte>();
if (netStream.CanRead)
{
byte[] buffer = new byte[256];
int bytesRead = 0;
do
{
bytesRead = netStream.Read(buffer, 0, buffer.Length);
responseData.AddRange(buffer);
Thread.Sleep(30);
//Log.Debug("Thread " + num + ": Bytes read: " + bytesRead + " - " + Encoding.UTF8.GetString(buffer));
} while (netStream.DataAvailable);
//Log.Debug("Raw TCP In: " + System.Text.Encoding.UTF8.GetString(responseData.ToArray()));
OscMessage response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray());
OnMessageReceived(response);
}
} catch(Exception e)
{
//Log.Debug("TCPSENDER - Receive Exception: " + e.ToString());
}
}
public byte[] SlipEncode(byte[] data)
{
List<byte> slipData = new List<byte>();
byte[] esc_end = { ESC, ESC_END };
byte[] esc_esc = { ESC, ESC_ESC };
byte[] end = { END };
int length = data.Length;
for (int i = 0; i < length; i++)
{
if (data[i] == END)
{
slipData.AddRange(esc_end);
}
else if (data[i] == ESC)
{
slipData.AddRange(esc_esc);
}
else
{
slipData.Add(data[i]);
}
}
slipData.AddRange(end);
return slipData.ToArray();
}
public void Close()
{
client.GetStream().Close();
client.Close();
}
protected virtual void OnMessageReceived(OscMessage msg)
{
if (MessageReceived != null)
MessageReceived(this, new MessageEventArgs() { Message = msg });
}
}
}