Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Net.Sockets;
- using System.Threading;
- namespace EasyTCP
- {
- public class TCP : IDisposable
- {
- public event BytesReceivedEventHandler BytesReceived;
- public delegate void BytesReceivedEventHandler(byte[] Bytes);
- public event ExceptionOccurredEventHandler ExceptionOccurred;
- public delegate void ExceptionOccurredEventHandler(Exception ex);
- public event SuccessfullySentEventHandler SuccessfullySent;
- public delegate void SuccessfullySentEventHandler(ulong SendID);
- private int Port;
- private string Address;
- private ulong SentCount = 0;
- private Socket Connection;
- private Thread SendThread;
- private Thread RecvThread;
- private Mutex ReadMutex = new Mutex(false);
- private ConcurrentQueue<SendMeta> SendQueue;
- private EventWaitHandle SendWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
- public Socket Socket
- {
- get { return Connection; }
- }
- public TCP(string Address, int Port)
- {
- this.Address = Address;
- this.Port = Port;
- }
- public void Close()
- {
- try
- {
- RecvThread.Abort();
- }
- catch (Exception) { }
- try
- {
- SendThread.Abort();
- }
- catch (Exception) { }
- try
- {
- Connection.Disconnect(false);
- }
- catch (Exception) { }
- try
- {
- Connection.Close();
- }
- catch (Exception) { }
- try
- {
- Connection.Dispose();
- }
- catch (Exception) { }
- }
- public bool TryConnect(byte[][] InitialSend)
- {
- if (Connection == null || !Connection.Connected)
- {
- try
- {
- Connection = new Socket(SocketType.Stream, ProtocolType.Tcp);
- Connection.Connect(Address, Port);
- if (RecvThread != null) RecvThread.Abort();
- if (SendThread != null) SendThread.Abort();
- SendQueue = new ConcurrentQueue<SendMeta>();
- RecvThread = new Thread(() =>
- {
- while (Connection.Connected)
- {
- try
- {
- List<byte> Data = new List<byte>();
- do
- {
- byte[] Buffer = new byte[512];
- Array.Resize(ref Buffer, Connection.Receive(Buffer, Buffer.Length, SocketFlags.None));
- Data.AddRange(Buffer);
- } while (Connection.Available > 0);
- BytesReceived(Data.ToArray());
- }
- catch (Exception ex)
- {
- ExceptionOccurred(ex);
- }
- }
- })
- { IsBackground = true };
- SendThread = new Thread(() =>
- {
- while (Connection.Connected)
- {
- SendWaitHandle.WaitOne();
- while (SendQueue.Count > 0 && Connection.Connected)
- {
- SendMeta Bytes;
- if (SendQueue.TryDequeue(out Bytes))
- {
- try
- {
- Connection.Send(Bytes.Bytes, Bytes.Bytes.Length, Bytes.Flag);
- SuccessfullySent(Bytes.SendID);
- }
- catch (Exception ex)
- {
- ExceptionOccurred(ex);
- }
- }
- }
- }
- })
- { IsBackground = true };
- RecvThread.Start();
- SendThread.Start();
- }
- catch (Exception ex)
- {
- ExceptionOccurred(ex);
- }
- }
- return false;
- }
- private struct SendMeta
- {
- public readonly ulong SendID;
- public readonly byte[] Bytes;
- public readonly SocketFlags Flag;
- public SendMeta(ulong SendID, byte[] Bytes, SocketFlags Flag)
- {
- this.SendID = SendID;
- this.Bytes = Bytes;
- this.Flag = Flag;
- }
- }
- public ulong Send(byte[] Bytes, SocketFlags Flag = SocketFlags.None)
- {
- try
- {
- ReadMutex.WaitOne();
- }
- catch (Exception) { }
- SendMeta newSendMeta = new SendMeta(SentCount, Bytes, Flag);
- SentCount++;
- SendQueue.Enqueue(newSendMeta);
- ReadMutex.ReleaseMutex();
- SendWaitHandle.Set();
- return newSendMeta.SendID;
- }
- public void Dispose()
- {
- Close();
- Connection.Close();
- Connection.Dispose();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment