using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;
namespace AutobotServer
{
/// <summary>
/// Delegate used by the events StdOutReceived and
/// StdErrReceived...
/// </summary>
public delegate void TcpDataReceivedHandler(object sender, TcpDataReceivedEventArgs e);
public delegate void HasDataHandler(object sender, TcpDataReceivedEventArgs e);
/// <summary>
/// Event Args for above delegate
/// </summary>
public class TcpDataReceivedEventArgs : EventArgs
{
/// <summary>
/// The text that was received
/// </summary>
public string Text;
/// <summary>
/// Constructor
/// </summary>
/// <param name="text">The text that was received for this event to be triggered.</param>
public TcpDataReceivedEventArgs(string text)
{
Text = text;
}
}
/// <summary>
/// This class Will Launch a tcp server Instance on an Accepted socket
/// Output from reading the TCP socket is returnd to GUI app for display
/// in textboxes, etc.
/// </summary>
public class ServerCaller : AsyncOperation
{
private System.Net.Sockets.Socket m_TcpSocket;
private System.Net.Sockets.NetworkStream NetworkStreamForClient;
private int m_iReadAmount;
private int m_iAmountRead;
private int m_iStartRead;
private byte[] m_ReadBytes;
/// Fired for the appriproate TCP events
public event TcpDataReceivedHandler TcpOutReceived;
public event TcpDataReceivedHandler TcpErrorReceived;
public event HasDataHandler HasDataEventCB;
/// Amount of time to sleep on threads while waiting for the process to finish.
public int SleepTime = 500;
/// The Parent Owner of this Process
public Object m_pParent;
MethodInvoker m_TCPReader;
IAsyncResult m_TCPReaderTag;
public ServerCaller(ISynchronizeInvoke isi, System.Net.Sockets.Socket a_TcpSocket)
: base(isi)
{
m_TcpSocket = a_TcpSocket;
m_iReadAmount = 0;
m_iAmountRead = 0;
m_iStartRead = 0;
m_ReadBytes = null;
}
public bool ReadAmount(int a_iReadamount)
{
if (null != NetworkStreamForClient && null != m_TcpSocket && m_TcpSocket.Connected && !CancelRequested && Interlocked.Equals(m_iStartRead, 0))
{
m_iReadAmount = a_iReadamount;
m_iAmountRead = 0;
m_ReadBytes = new byte[a_iReadamount];
Interlocked.Exchange(ref m_iStartRead, 1);
return true;
}
return false;
}
public void SendData(String a_sData)
{
if (null != NetworkStreamForClient)
{
try
{
Byte[] sendBytes = Encoding.ASCII.GetBytes(a_sData);
NetworkStreamForClient.WriteAsync(sendBytes, 0, sendBytes.Length);
NetworkStreamForClient.FlushAsync();
//NetworkStreamForClient.Write(sendBytes, 0, sendBytes.Length);
//NetworkStreamForClient.Flush();
}
catch (Exception e)
{
if (!CancelRequested)
{
FireAsync(TcpErrorReceived, this, new TcpDataReceivedEventArgs(e.ToString()));
}
}
}
}
private bool HasData()
{
if (null != NetworkStreamForClient && null != m_TcpSocket && m_TcpSocket.Connected)
{
return NetworkStreamForClient.DataAvailable;
}
return false;
}
protected override void DoWork()
{
NetworkStreamForClient = new System.Net.Sockets.NetworkStream(m_TcpSocket);
m_TCPReader = new MethodInvoker(ReadTcpOut);
m_TCPReaderTag = m_TCPReader.BeginInvoke(null, null);
// Wait for the process to end, or cancel it
while (!CancelRequested)
{
Thread.Sleep(SleepTime); // sleep
if (!m_TcpSocket.Connected)
{
Cancel();
}
else if (HasData())
{
FireAsync(HasDataEventCB, this, new TcpDataReceivedEventArgs(""));
}
}
try
{
if (m_TcpSocket.Connected)
{
m_TcpSocket.Close();
}
}
finally
{
BlockFlushConsole();
AcknowledgeCancel();
}
}
protected virtual void ReadTcpOut()
{
while (!CancelRequested)
{
bool bSleep = true;
try
{
if (null != NetworkStreamForClient && Interlocked.Equals(m_iStartRead, 1) && m_TcpSocket.Connected && NetworkStreamForClient.DataAvailable)
{
int iAmountReceived = NetworkStreamForClient.Read(m_ReadBytes, m_iAmountRead, m_iReadAmount - m_iAmountRead);
if (iAmountReceived > 0)
{
bSleep = false;
m_iAmountRead += iAmountReceived;
if (m_iAmountRead == m_iReadAmount && !CancelRequested)
{
string dataFromClient = System.Text.Encoding.ASCII.GetString(m_ReadBytes, 0, iAmountReceived);
Interlocked.Exchange(ref m_iStartRead, 0);
FireAsync(TcpOutReceived, this, new TcpDataReceivedEventArgs(dataFromClient));
}
}
}
}
catch (Exception e)
{
if (!CancelRequested)
{
FireAsync(TcpErrorReceived, this, new TcpDataReceivedEventArgs(e.ToString()));
}
}
if (bSleep && !CancelRequested)
{
System.Threading.Thread.Sleep(500);
}
}
}
protected override void BlockFlushConsole()
{
if (null != m_TCPReader)
{
m_TCPReader.EndInvoke(m_TCPReaderTag);
}
}
}
}