/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright (C) Marco Klein alias WorldRacer, WorldRacer92, WorldRacer_original *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace devNetworks
{
/// <summary>
/// This class represents a client
/// </summary>
public class Client
{
#region Public Attributes
/// <summary>
/// Socket. (TcpClient)
/// </summary>
public System.Net.Sockets.TcpClient Socket
{
get { return _Socket; }
set { _Socket = value; }
}
#endregion
#region Private Attributes
// Thread for handling server Messages
System.Threading.Thread _ClientThread = null;
// Socket to handle with
private System.Net.Sockets.TcpClient _Socket = null;
// IP-Adress of the endpoint
private string _IPAdress = string.Empty;
// Port to connect at the entpoint
private int _Port = 0;
// Contains whether we are connected or not.
private bool _Connected = false;
// Bufferlength
int _BufferLength = 4096;
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
System.Net.Sockets.NetworkStream _Stream;
// How shall the messages be encoded to?
System.Text.Encoding _EncodingInstance = System.Text.Encoding.ASCII;
#endregion
#region Constructor
/// <summary>
/// Initializes a Client
/// </summary>
/// <param name="IPAdress">IP-Adress of the endpoint</param>
/// <param name="Port">Port to connect at the entpoint</param>
/// <param name="ConnectImmediately">Should I connect directly?</param>
/// <param name="BufferLength">How long shall the received messages be?</param>
/// <param name="EncodingInstance">How shall the messages be encoded to?</param>
public Client(string IPAdress, int Port, System.Text.Encoding EncodingInstance, bool ConnectImmediately = false, int BufferLength = 4096)
{
// Save the values
if (BufferLength > 0)
{
_BufferLength = BufferLength;
}
else
{
_BufferLength = 4096;
}
_EncodingInstance = EncodingInstance;
// If we shall connect immediately...
if (ConnectImmediately)
{
try
{
// Create a socket which connects immediately
_Socket = new System.Net.Sockets.TcpClient(IPAdress, Port);
_Connected = _Socket.Connected;
}
catch (Exception)
{
}
}
else
{
// Else, initialize a new, not connecting socket
_Socket = new System.Net.Sockets.TcpClient();
_IPAdress = IPAdress;
_Port = Port;
}
}
#endregion
#region Private Methods
/// <summary>
/// Worker Function for client listening
/// </summary>
private void _ClientThreadFunc()
{
// Enter listening loop
while (true)
{
// Give the other threads 1 miliseconds to do their work, else a 100% CPU load is guaranteed.
System.Threading.Thread.Sleep(1);
// Message Bytes
Byte[] data = new Byte[_BufferLength];
// String to store the response ASCII representation.
string responseData = string.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = _Stream.Read(data, 0, data.Length);
// Placeholder for writing in the recieved data.
responseData = _EncodingInstance.GetString(data, 0, bytes);
// Call MessageReceived event, if it has event handlers
if (MessageRecieved != null)
{
MessageRecieved(this, responseData);
}
}
}
#endregion
#region Public Methods
/// <summary>
/// Sends a message to the Server
/// </summary>
/// <param name="Message">Message to send</param>
public void SendMessage(string Message)
{
// Convert string into bytes
byte[] msg = _EncodingInstance.GetBytes(Message);
// Send the bytes to the stream.
_Stream.Write(msg, 0, msg.Length);
}
/// <summary>
/// Connect to the endpoint
/// </summary>
/// <returns></returns>
public bool Connect()
{
// If we have an IP
if (_IPAdress == string.Empty || _Port == 0)
{
// If not, return false
return false;
}
else
{
// If there was a socket before
if (Socket != null)
{
// and if it was connected, disconnect it
if (!_Socket.Connected)
_Socket.Close();
}
else
{
// else create a new one.
_Socket = new System.Net.Sockets.TcpClient();
}
// If everything's fine, connect it.
_Socket.Connect(_IPAdress, _Port);
// If the socket is connected
if (_Socket.Connected)
{
// Retrieve a stream
_Stream = _Socket.GetStream();
// And start the listening thread
_ClientThread = new System.Threading.Thread(new System.Threading.ThreadStart(_ClientThreadFunc));
_ClientThread.Start();
}
// Last but not least, return success or fail message
return _Socket.Connected;
}
}
#endregion
#region Events
/// <summary>
/// Called when the client received a message
/// </summary>
/// <param name="sender">This ServerClient</param>
/// <param name="Message">Received message</param>
public delegate void MessageRecievedDelegate(object sender, string Message);
/// <summary>
/// Called when the client received a message
/// </summary>
public event MessageRecievedDelegate MessageRecieved;
#endregion
}
}