Skip to content

Instantly share code, notes, and snippets.

@CipherLab
Created July 11, 2014 13:12
Show Gist options
  • Save CipherLab/2d3c5139b11bf5e126e5 to your computer and use it in GitHub Desktop.
Save CipherLab/2d3c5139b11bf5e126e5 to your computer and use it in GitHub Desktop.
Threaded socket listener
using System;
using System.Threading;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Data.SqlClient;
using Timer = System.Windows.Forms.Timer;
using System.Diagnostics;
namespace CustomSocketListener
{
public class mytcp : TcpListener
{
public bool is_active;
public mytcp(IPAddress address, int port)
: base(address, port)
{ }
public void UsingProtectedMethods()
{
if (this.Active)
{
is_active = true;
//Socket s = this.Server;
//LingerOption lingerOption = new LingerOption(true, 10);
//s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerOption);
}
else
{
is_active = false;
}
}
}
public static class locker
{
public static object locked = new object();
}
public class SocketListener
{
public int ListenerID = 0;
public IPAddress IP = null;
public int port = 2210;
public int PortReadDelay = 10;
private int ThreadInterval = 100;
public Socket socket;
public bool Stopped = false;
public bool Pause = false;
public bool IsPaused = false;
public bool port_error = false;
public mytcp tcp = new mytcp(IPAddress.Parse("127.0.0.1"), 2210);
private bool StopListener = false;
private System.Threading.Timer ThreadTimer;
private AutoResetEvent autoEvent = new AutoResetEvent(false);
private TimerCallback timerDelegate;
public SocketListener()
{
timerDelegate = new TimerCallback(this.ThreadCommTimer_Tick);
ThreadTimer = new System.Threading.Timer(timerDelegate, autoEvent, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
}
public void Dispose()
{
ThreadTimer.Dispose();
}
public string Listen(int port_num)
{
tcp = new mytcp(IP, port_num);
tcp.Server.ReceiveBufferSize = 51200;
tcp.Server.SendBufferSize = 51200;
tcp.ExclusiveAddressUse = false;
tcp.Server.ReceiveTimeout = 0;
tcp.Server.LingerState.LingerTime = 0;
tcp.Server.LingerState.Enabled = false;
Stopped = false;
//SocketTimer.Tick += new EventHandler(SocketTimer_Tick);
//SocketTimer.Interval = PortReadDelay;
//SocketTimer.Enabled = true;
ThreadTimer.Change(ThreadInterval, ThreadInterval);
try
{
tcp.Start();
}
catch (Exception ex)
{
if (ex.Message.ToString() == "The requested address is not valid in its context")
{
return ("Invalid IP address. You may not be able to send or receive data through the ports.");
}
else
{
EventLogger.Log(ex.Message.ToString(),"GNPService");
}
}
finally
{
tcp.UsingProtectedMethods();
}
return "";
}
public void StopListening()
{
StopListener = true;
Application.DoEvents();
}
public void AcceptConnection()
{
socket = tcp.AcceptSocket();
}
public bool Connected = false;
private void ThreadCommTimer_Tick(Object stateInfo)
{
try
{
ThreadTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
}
catch
{
}
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
if (socket == null)
{
Connected = false;
}
else if (!socket.Connected)
{
Connected = false;
}
else if (!tcp.Server.Connected)
{
Connected = false;
}
else
{
Connected = true;
}
if (tcp.is_active)
{
if ((tcp.Pending()) && !Connected)
{
ConnectionRequest(ListenerID);
}
else if ((socket != null) && (socket.Available > 0))
{
bool pulling_from_socket = true;
List<byte> buffer = new List<byte>();
byte[] bArray = new byte[0];
try
{
while (pulling_from_socket)
{
if (socket.Available > 0)
{
byte[] from_socket = new byte[socket.Available];
socket.Receive(from_socket);
buffer.AddRange(from_socket);
}
else
{
pulling_from_socket = false;
}
System.Threading.Thread.Sleep(100);
}
bArray = buffer.ToArray();
}
catch (Exception ex)
{
EventLogger.Log("ThreadCommTimer_Tick:1-" + ex.Message, "GNPService");
}
lock (locker.locked)
{
try
{
var endpoint = ((IPEndPoint)socket.LocalEndPoint);
DataAvailable(bArray, ListenerID, endpoint.Port);
StringAvailable(System.Text.Encoding.Unicode.GetString(bArray, 0, bArray.Length), ListenerID);
}
catch (Exception ex)
{
EventLogger.Log("ThreadCommTimer_Tick:2-" + ex.Message, "GNPService");
}
}
}
}
else
{
port_error = true;
}
if (!StopListener)
{
autoEvent.Set();
ThreadTimer.Change(ThreadInterval, ThreadInterval);
}
else
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both );
while (socket.Available > 0)
{
byte[] from_socket = new byte[socket.Available];
socket.Receive(from_socket);
}
socket.Close();
}
Stopped = true;
tcp.Server.Close();
tcp.Stop();
}
}
public delegate void dlgConnectRequest(int SocketID);
public event dlgConnectRequest ConnectionRequest;
public delegate void dlgDataAvailable(byte[] DataReceived, int SocketID, int SocketNum);
public event dlgDataAvailable DataAvailable;
public delegate void dlgStringDataAvailable(string StringReceived, int SocketID);
public event dlgStringDataAvailable StringAvailable;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment