This is a simple tcp server for sending and receiving strings
now just to clarify, i know i could optimize it a bit and change the way the methods are implemented.
this server designed specifically for 1 client connection and termination. as a replacement for p2p connection.
dont ask why or what for, its a project im working on, and wanted to share it with the public. (yes, it is related to hacking)
i won't give the Client source code
Code:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpClassTest
{
class TcpServer
{
#region Props and objects
private TcpListener server;
private TcpClient client;
private const int MaxPacketSize = 0x1F4;
private Boolean isExit = false;
private BackgroundWorker ListenThread;
private BackgroundWorker ReceiveThread;
#endregion
#region Event Handlers
public event EventHandler<ClientConnectedEventsArgs> ClientConnected;
protected virtual void OnClientConnected(ClientConnectedEventsArgs args)
{
try
{
ClientConnected?.Invoke(this, args);
}
catch { }
}
public event EventHandler ListenStarted;
protected virtual void OnListenStarted(EventArgs args)
{
try
{
ListenStarted.Invoke(this, args);
}
catch { }
}
public event EventHandler<MessageReceiveEventArgs> MessageReceived;
protected virtual void OnMessageReceived(MessageReceiveEventArgs args)
{
try
{
MessageReceived?.Invoke(this, args);
}
catch { }
}
#endregion
#region Methods
/// <summary>
/// Start listen for incoming connectings on the specific port
/// </summary>
/// <param name="port">the port to bind the socket to</param>
public void Start(int port) {
string addr = null;
foreach(var ip in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if(ip.AddressFamily == AddressFamily.InterNetwork)
{
addr = ip.ToString();
}
}
server = new TcpListener(new IPEndPoint(IPAddress.Parse(addr), port));
ListenThread = new BackgroundWorker();
ListenThread.WorkerReportsProgress = true;
ListenThread.WorkerSupportsCancellation = true;
ListenThread.DoWork += ListenThread_DoWork;
ListenThread.ProgressChanged += ListenThread_ProgressChanged;
ListenThread.RunWorkerAsync();
ReceiveThread = new BackgroundWorker();
ReceiveThread.WorkerReportsProgress = true;
ReceiveThread.WorkerSupportsCancellation = true;
ReceiveThread.DoWork += ReceiveThread_DoWork;
ReceiveThread.ProgressChanged += ReceiveThread_ProgressChanged;
OnListenStarted(EventArgs.Empty);
}
/// <summary>
/// Stops the server and dispose everything related to TcpServer class
/// </summary>
public void Stop() {
Dispose();
}
/// <summary>
/// Dispose everything in TcpServer class
/// </summary>
private void Dispose() {
client = null;
server = null;
ListenThread.DoWork -= ListenThread_DoWork;
ListenThread.ProgressChanged -= ListenThread_ProgressChanged;
ListenThread = null;
ReceiveThread.DoWork -= ReceiveThread_DoWork;
ReceiveThread.ProgressChanged -= ReceiveThread_ProgressChanged;
ReceiveThread = null;
ClientConnected = null;
MessageReceived = null;
ListenStarted = null;
}
/// <summary>
/// Send message to the connected client
/// </summary>
public void SendMessage(string msg)
{
if(client != null && clien*****nnected)
{
byte[] buff = Encoding.ASCII.GetBytes(msg);
client.Client.Send(buff);
}
}
#endregion
#region ListenThread
private void ListenThread_DoWork(object sender, DoWorkEventArgs e)
{
if(!isExit)
{
///
/// Try to start the server
///
try
{
server.Start();
}
catch(Exception r)
{
isExit = true;
Debug.Write("[ERROR] - Failed to start server\n" + r.Source + "\n" + r.Message + "\n" + r.InnerException + "\n" + r.StackTrace + "\n" + r.HResult);
}
}
while (!isExit)
{
///
/// Accept the pending client request and connect him to the server, then stop listen for connections
///
try
{
client = server.AcceptTcpClient();
server.Stop();
ListenThread.ReportProgress(0, "cmd:connected");
ReceiveThread.RunWorkerAsync();
Debug.Write("[SUCCESS] - User connected to server\n");
Debug.Write("[SUCCESS] - Server stopped listening for connecions\n");
isExit = true;
break;
}
catch (Exception r)
{
isExit = true;
Debug.Write("[ERROR] - User failed to connect...\n");
Debug.Write("[ERROR] - Failed to connect client to the server\n" + r.Source + "\n" + r.Message + "\n" + r.InnerException + "\n" + r.StackTrace + "\n" + r.HResult);
}
}
}
private void ListenThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Raise the custom event
try
{
ClientConnectedEventsArgs args = new ClientConnectedEventsArgs();
args.Client = client;
OnClientConnected(args);
}
catch { }
}
#endregion
#region ReceiveThread
private void ReceiveThread_DoWork(object sender, DoWorkEventArgs e)
{
while(!isExit)
{
try
{
if(client != null)
{
byte[] buff = new byte[MaxPacketSize];
client.Client.Receive(buff);
string s = Encoding.ASCII.GetString(buff);
ReceiveThread.ReportProgress(0, s);
}
}
catch
{
isExit = true;
Debug.Write("[ERROR] - Failed to get message from client\nClient is null or disconnected");
}
}
}
private void ReceiveThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
try
{
MessageReceiveEventArgs args = new MessageReceiveEventArgs();
args.Message = e.UserState as string;
OnMessageReceived(args);
}
catch { }
}
#endregion
}
#region Custom Event Args
public class MessageReceiveEventArgs : EventArgs
{
public string Message { get; set; }
}
public class ClientConnectedEventsArgs : EventArgs
{
public TcpClient Client { get; set; }
}
#endregion
}