Created
April 14, 2012 01:43
-
-
Save bschwind/2381447 to your computer and use it in GitHub Desktop.
Implements a simple TCP client
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Threading; | |
namespace GraphicsToolkit.Networking | |
{ | |
public delegate void ClientHandlePacketData(byte[] data, int bytesRead); | |
/// <summary> | |
/// Implements a simple TCP client which connects to a specified server and | |
/// raises C# events when data is received from the server | |
/// </summary> | |
public class Client | |
{ | |
public event ClientHandlePacketData OnDataReceived; | |
private TcpClient tcpClient; | |
private NetworkStream clientStream; | |
private NetworkBuffer buffer; | |
private int writeBufferSize = 1024; | |
private int readBufferSize = 1024; | |
private int port; | |
private bool started = false; | |
/// <summary> | |
/// Constructs a new client | |
/// </summary> | |
public Client() | |
{ | |
buffer = new NetworkBuffer(); | |
buffer.WriteBuffer = new byte[writeBufferSize]; | |
buffer.ReadBuffer = new byte[readBufferSize]; | |
buffer.CurrentWriteByteCount = 0; | |
} | |
/// <summary> | |
/// Initiates a TCP connection to a TCP server with a given address and port | |
/// </summary> | |
/// <param name="ipAddress">The IP address (IPV4) of the server</param> | |
/// <param name="port">The port the server is listening on</param> | |
public void ConnectToServer(string ipAddress, int port) | |
{ | |
this.port = port; | |
tcpClient = new TcpClient(ipAddress, port); | |
clientStream = tcpClient.GetStream(); | |
Console.WriteLine("Connected to server, listening for packets"); | |
Thread t = new Thread(new ThreadStart(ListenForPackets)); | |
started = true; | |
t.Start(); | |
} | |
/// <summary> | |
/// This method runs on its own thread, and is responsible for | |
/// receiving data from the server and raising an event when data | |
/// is received | |
/// </summary> | |
private void ListenForPackets() | |
{ | |
int bytesRead; | |
while (started) | |
{ | |
bytesRead = 0; | |
try | |
{ | |
//Blocks until a message is received from the server | |
bytesRead = clientStream.Read(buffer.ReadBuffer, 0, readBufferSize); | |
} | |
catch | |
{ | |
//A socket error has occurred | |
Console.WriteLine("A socket error has occurred with the client socket " + tcpClient.ToString()); | |
break; | |
} | |
if (bytesRead == 0) | |
{ | |
//The server has disconnected | |
break; | |
} | |
if (OnDataReceived != null) | |
{ | |
//Send off the data for other classes to handle | |
OnDataReceived(buffer.ReadBuffer, bytesRead); | |
} | |
Thread.Sleep(15); | |
} | |
started = false; | |
Disconnect(); | |
} | |
/// <summary> | |
/// Adds data to the packet to be sent out, but does not send it across the network | |
/// </summary> | |
/// <param name="data">The data to be sent</param> | |
public void AddToPacket(byte[] data) | |
{ | |
if (buffer.CurrentWriteByteCount + data.Length > buffer.WriteBuffer.Length) | |
{ | |
FlushData(); | |
} | |
Array.ConstrainedCopy(data, 0, buffer.WriteBuffer, buffer.CurrentWriteByteCount, data.Length); | |
buffer.CurrentWriteByteCount += data.Length; | |
} | |
/// <summary> | |
/// Flushes all outgoing data to the server | |
/// </summary> | |
public void FlushData() | |
{ | |
clientStream.Write(buffer.WriteBuffer, 0, buffer.CurrentWriteByteCount); | |
clientStream.Flush(); | |
buffer.CurrentWriteByteCount = 0; | |
} | |
/// <summary> | |
/// Sends the byte array data immediately to the server | |
/// </summary> | |
/// <param name="data"></param> | |
public void SendImmediate(byte[] data) | |
{ | |
AddToPacket(data); | |
FlushData(); | |
} | |
/// <summary> | |
/// Tells whether we're connected to the server | |
/// </summary> | |
/// <returns></returns> | |
public bool IsConnected() | |
{ | |
return started && tcpClient.Connected; | |
} | |
/// <summary> | |
/// Disconnect from the server | |
/// </summary> | |
public void Disconnect() | |
{ | |
if (tcpClient == null) | |
{ | |
return; | |
} | |
Console.WriteLine("Disconnected from server"); | |
tcpClient.Close(); | |
started = false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment