//----
        internal static System.Net.Sockets.Socket GetAConnectedSocket()
        {
            Socket s = SocketPair.GetConnectedSocket();

            Debug.Assert(s != null);
            Debug.Assert(s.Connected);
            return(s);
        }
        public void PassHandle()
        {
            PosixResult result;

            // server socket
            var serverSocket  = Socket.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, blocking: true);
            var serverAddress = new IPEndPointStruct(IPAddress.Loopback, 0);

            serverSocket.Bind(serverAddress);
            serverAddress = serverSocket.GetLocalIPAddress();
            serverSocket.Listen(10);

            // client connect
            var clientSocket = Socket.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, blocking: true);

            clientSocket.TryConnect(serverAddress);

            // accept and pass socket
            SocketPair pair = Socket.CreatePair(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified, blocking: false);

            result = serverSocket.TryAcceptAndSendHandleTo(pair.Socket1);
            Assert.True(result.IsSuccess);

            // receive accept socket
            int acceptSocketFd;

            result = SocketInterop.ReceiveSocket(pair.Socket2, out acceptSocketFd, blocking: true);
            Socket acceptSocket = result.IsSuccess ? new Socket(acceptSocketFd) : null;

            Assert.True(result.IsSuccess);
            Assert.Equal(1, result.Value);

            // Send
            result = clientSocket.TrySend(s_data);

            // Receive
            byte[] receiveBuffer = new byte[10];
            result = acceptSocket.TryReceive(new ArraySegment <byte>(receiveBuffer));
            Assert.True(result.IsSuccess);
            Assert.Equal(s_data.Count, result.Value);

            // Close
            pair.Dispose();
            serverSocket.Dispose();
            clientSocket.Dispose();
            acceptSocket.Dispose();
        }
            //--------
            internal static Socket GetConnectedSocket()
            {
                // No need for locking etc here, as it's ok to make one or more (not
                // many hopefully however!)  The socket (is meant!) to be only used on
                // initialising the base NetworkStream, so it doesn't matter if the
                // SocketPair is finalized either.  Better to create only one, hence
                // why we cache it.
                // Careful of a race between accessing it, it becoming null, and the
                // Finalizer running, so keep a reference locally.
                SocketPair sp = m_SocketPair;

                if (sp == null || !sp.Alive)
                {
                    m_SocketPair = sp = SocketPair.Create();
                }
                return(sp.m_cli);
            }
        public void SocketPair()
        {
            SocketPair  pair = Socket.CreatePair(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified, blocking: false);
            PosixResult result;

            Socket socket1 = new Socket(pair.Socket1);
            Socket socket2 = new Socket(pair.Socket2);

            // Send
            result = socket1.TrySend(s_data);

            // Receive
            byte[] receiveBuffer = new byte[10];
            result = socket2.TryReceive(new ArraySegment <byte>(receiveBuffer));
            Assert.True(result.IsSuccess);
            Assert.Equal(s_data.Count, result.Value);

            // Close
            socket1.Dispose();
            socket2.Dispose();
        }
        private void ReadImpl()
        {
            List <IntPtr> dead = null, active = new List <IntPtr>();

            IntPtr[] readSockets   = EmptyPointers, errorSockets = EmptyPointers;
            long     lastHeartbeat = Environment.TickCount;

            SocketPair[] allSocketPairs = null;
            while (true)
            {
                active.Clear();
                if (dead != null)
                {
                    dead.Clear();
                }

                // this check is actually a pace-maker; sometimes the Timer callback stalls for
                // extended periods of time, which can cause socket disconnect
                long now = Environment.TickCount;
                if (unchecked (now - lastHeartbeat) >= 15000)
                {
                    lastHeartbeat = now;
                    lock (socketLookup)
                    {
                        if (allSocketPairs == null || allSocketPairs.Length != socketLookup.Count)
                        {
                            allSocketPairs = new SocketPair[socketLookup.Count];
                        }
                        socketLookup.Values.CopyTo(allSocketPairs, 0);
                    }
                    foreach (var pair in allSocketPairs)
                    {
                        var callback = pair.Callback;
                        if (callback != null)
                        {
                            try { callback.OnHeartbeat(); } catch { }
                        }
                    }
                }


                lock (socketLookup)
                {
                    if (isDisposed)
                    {
                        return;
                    }

                    if (socketLookup.Count == 0)
                    {
                        // if empty, give it a few seconds chance before exiting
                        Monitor.Wait(socketLookup, TimeSpan.FromSeconds(20));
                        if (socketLookup.Count == 0)
                        {
                            return;                          // nothing new came in, so exit
                        }
                    }
                    foreach (var pair in socketLookup)
                    {
                        var socket = pair.Value.Socket;
                        if (socket.Handle == pair.Key && socket.Connected)
                        {
                            if (pair.Value.Socket.Connected)
                            {
                                active.Add(pair.Key);
                            }
                            else
                            {
                                (dead ?? (dead = new List <IntPtr>())).Add(pair.Key);
                            }
                        }
                    }
                    if (dead != null && dead.Count != 0)
                    {
                        foreach (var socket in dead)
                        {
                            socketLookup.Remove(socket);
                        }
                    }
                }
                int pollingSockets = active.Count;
                if (pollingSockets == 0)
                {
                    // nobody had actual sockets; just sleep
                    Thread.Sleep(10);
                    continue;
                }

                if (readSockets.Length < active.Count + 1)
                {
                    ConnectionMultiplexer.TraceWithoutContext("Resizing socket array for " + active.Count + " sockets");
                    readSockets  = new IntPtr[active.Count + 6]; // leave so space for growth
                    errorSockets = new IntPtr[active.Count + 6];
                }
                readSockets[0] = errorSockets[0] = (IntPtr)active.Count;
                active.CopyTo(readSockets, 1);
                active.CopyTo(errorSockets, 1);
                int ready;
                try
                {
                    var timeout = new TimeValue(1000);
                    ready = select(0, readSockets, null, errorSockets, ref timeout);
                    if (ready <= 0)
                    {
                        continue; // -ve typically means a socket was disposed just before; just retry
                    }

                    ConnectionMultiplexer.TraceWithoutContext((int)readSockets[0] != 0, "Read sockets: " + (int)readSockets[0]);
                    ConnectionMultiplexer.TraceWithoutContext((int)errorSockets[0] != 0, "Error sockets: " + (int)errorSockets[0]);
                }
                catch (Exception ex)
                { // this typically means a socket was disposed just before; just retry
                    Trace.WriteLine(ex.Message);
                    continue;
                }

                int queueCount = (int)readSockets[0];
                lock (readQueue)
                {
                    for (int i = 1; i <= queueCount; i++)
                    {
                        readQueue.Enqueue(readSockets[i]);
                    }
                }
                queueCount = (int)errorSockets[0];
                lock (errorQueue)
                {
                    for (int i = 1; i <= queueCount; i++)
                    {
                        errorQueue.Enqueue(errorSockets[i]);
                    }
                }


                if (ready >= 5) // number of sockets we should attempt to process by ourself before asking for help
                {
                    // seek help, work in parallel, then synchronize
                    var obj = new QueueDrainSyncLock(this);
                    lock (obj)
                    {
                        ThreadPool.QueueUserWorkItem(HelpProcessItems, obj);
                        ProcessItems();
                        if (!obj.Consume())
                        {   // then our worker arrived and picked up work; we need
                            // to let it finish; note that if it *didn't* get that far
                            // yet, the Consume() call will mean that it never tries
                            Monitor.Wait(obj);
                        }
                    }
                }
                else
                {
                    // just do it ourself
                    ProcessItems();
                }
            }
        }
        private void ReadImpl()
        {
            List<IntPtr> dead = null, active = new List<IntPtr>();
            List<ISocketCallback> activeCallbacks = new List<ISocketCallback>();
            IntPtr[] readSockets = EmptyPointers, errorSockets = EmptyPointers;
            long lastHeartbeat = Environment.TickCount;
            SocketPair[] allSocketPairs = null;
            while (true)
            {
                managerState = ManagerState.CheckForHeartbeat;
                active.Clear();
                activeCallbacks.Clear();
                if (dead != null) dead.Clear();

                // this check is actually a pace-maker; sometimes the Timer callback stalls for
                // extended periods of time, which can cause socket disconnect
                long now = Environment.TickCount;
                if (unchecked(now - lastHeartbeat) >= 15000)
                {
                    managerState = ManagerState.ExecuteHeartbeat;
                    lastHeartbeat = now;
                    lock (socketLookup)
                    {
                        if (allSocketPairs == null || allSocketPairs.Length != socketLookup.Count)
                            allSocketPairs = new SocketPair[socketLookup.Count];
                        socketLookup.Values.CopyTo(allSocketPairs, 0);
                    }
                    foreach (var pair in allSocketPairs)
                    {
                        var callback = pair.Callback;
                        if (callback != null) try { callback.OnHeartbeat(); } catch { }
                    }
                }

                managerState = ManagerState.LocateActiveSockets;
                lock (socketLookup)
                {
                    if (isDisposed) return;

                    if (socketLookup.Count == 0)
                    {
                        // if empty, give it a few seconds chance before exiting
                        managerState = ManagerState.NoSocketsPause;
                        Monitor.Wait(socketLookup, TimeSpan.FromSeconds(20));
                        if (socketLookup.Count == 0) return; // nothing new came in, so exit
                    }
                    managerState = ManagerState.PrepareActiveSockets;
                    foreach (var pair in socketLookup)
                    {
                        var socket = pair.Value.Socket;
                        if (socket.Handle == pair.Key && socket.Connected)
                            if (pair.Value.Socket.Connected)
                            {
                                active.Add(pair.Key);
                                activeCallbacks.Add(pair.Value.Callback);
                            }
                            else
                            {
                                (dead ?? (dead = new List<IntPtr>())).Add(pair.Key);
                            }
                    }
                    if (dead != null && dead.Count != 0)
                    {
                        managerState = ManagerState.CullDeadSockets;
                        foreach (var socket in dead) socketLookup.Remove(socket);
                    }
                }
                int pollingSockets = active.Count;
                if (pollingSockets == 0)
                {
                    // nobody had actual sockets; just sleep
                    managerState = ManagerState.NoActiveSocketsPause;
                    Thread.Sleep(10);
                    continue;
                }

                if (readSockets.Length < active.Count + 1)
                {
                    managerState = ManagerState.GrowingSocketArray;
                    ConnectionMultiplexer.TraceWithoutContext("Resizing socket array for " + active.Count + " sockets");
                    readSockets = new IntPtr[active.Count + 6]; // leave so space for growth
                    errorSockets = new IntPtr[active.Count + 6];
                }
                managerState = ManagerState.CopyingPointersForSelect;
                readSockets[0] = errorSockets[0] = (IntPtr)active.Count;
                active.CopyTo(readSockets, 1);
                active.CopyTo(errorSockets, 1);
                int ready;
                try
                {
                    var timeout = new TimeValue(1000);
                    managerState = ManagerState.ExecuteSelect;
                    ready = select(0, readSockets, null, errorSockets, ref timeout);
                    managerState = ManagerState.ExecuteSelectComplete;
                    if (ready <= 0) // -ve typically means a socket was disposed just before; just retry
                    {
                        bool hasWorkToDo = false;
                        if (ready == 0)
                        {
                            managerState = ManagerState.CheckForStaleConnections;
                            foreach (var s in activeCallbacks)
                            {
                                if (s.IsDataAvailable)
                                {
                                    hasWorkToDo = true;
                                }
                                else
                                {
                                    s.CheckForStaleConnection();
                                }
                            }
                        }
                        else
                        {
                            lastErrorTicks = Environment.TickCount;
                        }
                        if (!hasWorkToDo)
                        {
                            continue; 
                        }
                    }
                    ConnectionMultiplexer.TraceWithoutContext((int)readSockets[0] != 0, "Read sockets: " + (int)readSockets[0]);
                    ConnectionMultiplexer.TraceWithoutContext((int)errorSockets[0] != 0, "Error sockets: " + (int)errorSockets[0]);
                }
                catch (Exception ex)
                { // this typically means a socket was disposed just before; just retry
                    Trace.WriteLine(ex.Message);
                    continue;
                }

                bool haveWork = false;
                int queueCount = (int)readSockets[0];
                if (queueCount != 0)
                {
                    managerState = ManagerState.EnqueueRead;
                    lock (readQueue)
                    {
                        for (int i = 1; i <= queueCount; i++)
                        {
                            var callback = GetCallback(readSockets[i]);
                            if (callback != null)
                            {
                                readQueue.Enqueue(callback);
                                haveWork = true;
                            }
                        }
                    }
                }
                queueCount = (int)errorSockets[0];
                if (queueCount != 0)
                {
                    managerState = ManagerState.EnqueueError;
                    lock (errorQueue)
                    {
                        for (int i = 1; i <= queueCount; i++)
                        {
                            var callback = GetCallback(errorSockets[i]);
                            if (callback != null)
                            {
                                errorQueue.Enqueue(callback);
                                haveWork = true;
                            }
                        }
                    }
                }
                if(!haveWork)
                {
                    // edge case: select is returning 0, but data could still be available
                    managerState = ManagerState.EnqueueReadFallback;
                    lock (readQueue)
                    {
                        foreach (var callback in activeCallbacks)
                        {
                            if(callback.IsDataAvailable)
                            {
                                readQueue.Enqueue(callback);
                            }
                        }
                    }
                }


                if (ready >= 5) // number of sockets we should attempt to process by ourself before asking for help
                {
                    // seek help, work in parallel, then synchronize
                    var obj = new QueueDrainSyncLock(this);
                    lock (obj)
                    {
                        managerState = ManagerState.RequestAssistance;
                        ThreadPool.QueueUserWorkItem(HelpProcessItems, obj);
                        managerState = ManagerState.ProcessQueues;
                        ProcessItems(true);
                        if (!obj.Consume())
                        {   // then our worker arrived and picked up work; we need
                            // to let it finish; note that if it *didn't* get that far
                            // yet, the Consume() call will mean that it never tries
                            Monitor.Wait(obj);
                        }
                    }
                }
                else
                {
                    // just do it ourself
                    managerState = ManagerState.ProcessQueues;
                    ProcessItems(true);
                }
            }
        }
Beispiel #7
0
        private void ReadImpl()
        {
            List <IntPtr>          dead = null, active = new List <IntPtr>();
            List <ISocketCallback> activeCallbacks = new List <ISocketCallback>();

            IntPtr[] readSockets   = EmptyPointers, errorSockets = EmptyPointers;
            long     lastHeartbeat = Environment.TickCount;

            SocketPair[] allSocketPairs = null;
            while (true)
            {
                managerState = ManagerState.CheckForHeartbeat;
                active.Clear();
                activeCallbacks.Clear();
                if (dead != null)
                {
                    dead.Clear();
                }

                // this check is actually a pace-maker; sometimes the Timer callback stalls for
                // extended periods of time, which can cause socket disconnect
                long now = Environment.TickCount;
                if (unchecked (now - lastHeartbeat) >= 15000)
                {
                    managerState  = ManagerState.ExecuteHeartbeat;
                    lastHeartbeat = now;
                    lock (socketLookup)
                    {
                        if (allSocketPairs == null || allSocketPairs.Length != socketLookup.Count)
                        {
                            allSocketPairs = new SocketPair[socketLookup.Count];
                        }
                        socketLookup.Values.CopyTo(allSocketPairs, 0);
                    }
                    foreach (var pair in allSocketPairs)
                    {
                        var callback = pair.Callback;
                        if (callback != null)
                        {
                            try { callback.OnHeartbeat(); } catch { }
                        }
                    }
                }

                managerState = ManagerState.LocateActiveSockets;
                lock (socketLookup)
                {
                    if (isDisposed)
                    {
                        return;
                    }

                    if (socketLookup.Count == 0)
                    {
                        // if empty, give it a few seconds chance before exiting
                        managerState = ManagerState.NoSocketsPause;
                        Monitor.Wait(socketLookup, TimeSpan.FromSeconds(20));
                        if (socketLookup.Count == 0)
                        {
                            return;                          // nothing new came in, so exit
                        }
                    }
                    managerState = ManagerState.PrepareActiveSockets;
                    foreach (var pair in socketLookup)
                    {
                        var socket = pair.Value.Socket;
                        if (socket.Handle == pair.Key && socket.Connected)
                        {
                            if (pair.Value.Socket.Connected)
                            {
                                active.Add(pair.Key);
                                activeCallbacks.Add(pair.Value.Callback);
                            }
                            else
                            {
                                (dead ?? (dead = new List <IntPtr>())).Add(pair.Key);
                            }
                        }
                    }
                    if (dead != null && dead.Count != 0)
                    {
                        managerState = ManagerState.CullDeadSockets;
                        foreach (var socket in dead)
                        {
                            socketLookup.Remove(socket);
                        }
                    }
                }
                int pollingSockets = active.Count;
                if (pollingSockets == 0)
                {
                    // nobody had actual sockets; just sleep
                    managerState = ManagerState.NoActiveSocketsPause;
                    Thread.Sleep(10);
                    continue;
                }

                if (readSockets.Length < active.Count + 1)
                {
                    managerState = ManagerState.GrowingSocketArray;
                    ConnectionMultiplexer.TraceWithoutContext("Resizing socket array for " + active.Count + " sockets");
                    readSockets  = new IntPtr[active.Count + 6]; // leave so space for growth
                    errorSockets = new IntPtr[active.Count + 6];
                }
                managerState   = ManagerState.CopyingPointersForSelect;
                readSockets[0] = errorSockets[0] = (IntPtr)active.Count;
                active.CopyTo(readSockets, 1);
                active.CopyTo(errorSockets, 1);
                int ready;
                try
                {
                    var timeout = new TimeValue(1000);
                    managerState = ManagerState.ExecuteSelect;
                    ready        = select(0, readSockets, null, errorSockets, ref timeout);
                    managerState = ManagerState.ExecuteSelectComplete;
                    if (ready <= 0) // -ve typically means a socket was disposed just before; just retry
                    {
                        bool hasWorkToDo = false;
                        if (ready == 0)
                        {
                            managerState = ManagerState.CheckForStaleConnections;
                            foreach (var s in activeCallbacks)
                            {
                                if (s.IsDataAvailable)
                                {
                                    hasWorkToDo = true;
                                }
                                else
                                {
#pragma warning disable 0420
                                    s.CheckForStaleConnection(ref managerState);
#pragma warning restore 0420
                                }
                            }
                            managerState = ManagerState.CheckForStaleConnectionsDone;
                        }
                        else
                        {
                            lastErrorTicks = Environment.TickCount;
                        }
                        if (!hasWorkToDo)
                        {
                            continue;
                        }
                    }
                    ConnectionMultiplexer.TraceWithoutContext((int)readSockets[0] != 0, "Read sockets: " + (int)readSockets[0]);
                    ConnectionMultiplexer.TraceWithoutContext((int)errorSockets[0] != 0, "Error sockets: " + (int)errorSockets[0]);
                }
                catch (Exception ex)
                { // this typically means a socket was disposed just before; just retry
                    Trace.WriteLine(ex.Message);
                    continue;
                }

                bool haveWork   = false;
                int  queueCount = (int)readSockets[0];
                if (queueCount != 0)
                {
                    managerState = ManagerState.EnqueueRead;
                    lock (readQueue)
                    {
                        for (int i = 1; i <= queueCount; i++)
                        {
                            var callback = GetCallback(readSockets[i]);
                            if (callback != null)
                            {
                                readQueue.Enqueue(callback);
                                haveWork = true;
                            }
                        }
                    }
                }
                queueCount = (int)errorSockets[0];
                if (queueCount != 0)
                {
                    managerState = ManagerState.EnqueueError;
                    lock (errorQueue)
                    {
                        for (int i = 1; i <= queueCount; i++)
                        {
                            var callback = GetCallback(errorSockets[i]);
                            if (callback != null)
                            {
                                errorQueue.Enqueue(callback);
                                haveWork = true;
                            }
                        }
                    }
                }
                if (!haveWork)
                {
                    // edge case: select is returning 0, but data could still be available
                    managerState = ManagerState.EnqueueReadFallback;
                    lock (readQueue)
                    {
                        foreach (var callback in activeCallbacks)
                        {
                            if (callback.IsDataAvailable)
                            {
                                readQueue.Enqueue(callback);
                            }
                        }
                    }
                }


                if (ready >= 5) // number of sockets we should attempt to process by ourself before asking for help
                {
                    // seek help, work in parallel, then synchronize
                    var obj = new QueueDrainSyncLock(this);
                    lock (obj)
                    {
                        managerState = ManagerState.RequestAssistance;
                        ThreadPool.QueueUserWorkItem(HelpProcessItems, obj);
                        managerState = ManagerState.ProcessQueues;
                        ProcessItems(true);
                        if (!obj.Consume())
                        {   // then our worker arrived and picked up work; we need
                            // to let it finish; note that if it *didn't* get that far
                            // yet, the Consume() call will mean that it never tries
                            Monitor.Wait(obj);
                        }
                    }
                }
                else
                {
                    // just do it ourself
                    managerState = ManagerState.ProcessQueues;
                    ProcessItems(true);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Message callback function
        /// Send user data back based on first connect or message
        /// </summary>
        /// <param name="AR"></param>
        private static void ReceiveCallback(IAsyncResult AR)
        {
            Socket current = (Socket)AR.AsyncState;
            int    received;

            if (!current.Connected)
            {
                return;
            }
            try
            {
                received = current.EndReceive(AR);
            }
            catch (SocketException)
            {
                Console.WriteLine("Client forcefully disconnected");
                // Don't shutdown because the socket may be disposed and its disconnected anyway.
                current.Close();
                SocketPair socketToRemove = null;
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket.Equals(current))
                    {
                        socketToRemove = s;
                        break;
                    }
                }
                if (socketToRemove != null)
                {
                    clientSockets.Remove(socketToRemove);
                    T2SClientMessage otherClient = new T2SClientMessage()
                    {
                        Connected = false,
                        MacAddr   = socketToRemove.MacAddr
                    };
                    byte[] otherClientBuffer        = MainWindow.ObjectToByteArray(otherClient);
                    byte[] otherClientBufferMessage = new byte[otherClientBuffer.Length + 33]; //message to send; appends length of header
                    string otherClientHeader        = otherClientBuffer.Length.ToString();
                    for (int i = otherClientHeader.Length; i < 32; i++)
                    {
                        otherClientHeader += " "; //Append empty spaces until header is max length (32)
                    }
                    otherClientHeader += "|";

                    Array.Copy(Encoding.ASCII.GetBytes(otherClientHeader), otherClientBufferMessage, 33);
                    Array.Copy(otherClientBuffer, 0, otherClientBufferMessage, 33, otherClientBuffer.Length);

                    //Sendto everyone
                    foreach (SocketPair s in clientSockets)
                    {
                        s.socket.Send(otherClientBufferMessage);
                    }
                }
                return;
            }

            if (received == 0)
            {
                Console.WriteLine("No bytes received; closing socket");
                SocketPair socketToRemove = null;
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket.Equals(current))
                    {
                        socketToRemove = s;
                        break;
                    }
                }
                if (socketToRemove.socket.Connected)
                {
                    socketToRemove.socket.Close();
                }
                clientSockets.Remove(socketToRemove);
                T2SClientMessage otherClient = new T2SClientMessage()
                {
                    Connected = false,
                    MacAddr   = socketToRemove.MacAddr
                };
                byte[] otherClientBuffer        = MainWindow.ObjectToByteArray(otherClient);
                byte[] otherClientBufferMessage = new byte[otherClientBuffer.Length + 33]; //message to send; appends length of header
                string otherClientHeader        = otherClientBuffer.Length.ToString();
                for (int i = otherClientHeader.Length; i < 32; i++)
                {
                    otherClientHeader += " "; //Append empty spaces until header is max length (32)
                }
                otherClientHeader += "|";

                Array.Copy(Encoding.ASCII.GetBytes(otherClientHeader), otherClientBufferMessage, 33);
                Array.Copy(otherClientBuffer, 0, otherClientBufferMessage, 33, otherClientBuffer.Length);

                //Sendto everyone
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket.Connected)
                    {
                        s.socket.Send(otherClientBufferMessage);
                    }
                }
                return;
            }

            byte[] recBuf = new byte[received]; //Received buffer which should be the header to tell us the buffer length of the json message (should be length 33 with pipe at the end)
            Array.Copy(buffer, recBuf, received);

            //Get until header is filled
            while (received < 33)
            {
                byte[] tempBuffer      = new byte[33 - received];
                int    appendableBytes = current.Receive(tempBuffer, 33 - received, SocketFlags.None);
                Array.Copy(tempBuffer, 0, recBuf, received, tempBuffer.Length);
                received += appendableBytes;
            }

            int headerReceived;

            if (Int32.TryParse(Encoding.ASCII.GetString(recBuf).Split('|')[0], out headerReceived))
            {
                recBuf   = new byte[headerReceived];
                received = current.Receive(recBuf, headerReceived, SocketFlags.None);
                //Get until object is filled
                while (received < headerReceived)
                {
                    byte[] tempBuffer      = new byte[headerReceived - received];
                    int    appendableBytes = current.Receive(tempBuffer, headerReceived - received, SocketFlags.None);
                    Array.Copy(tempBuffer, 0, recBuf, received, tempBuffer.Length);
                    received += appendableBytes;
                }
            }
            byte[] temp = new byte[recBuf.Length];
            Array.Copy(recBuf, temp, temp.Length);
            string header = recBuf.Length.ToString();

            //If the header length is larger than the maximum length, we're gonna assume that the dude is trying to destroy someone with a fat receive.
            //There's no reason for something to be this large
            //Therefore, just let the sender know that their message is waaaay too big
            if (header.Length < 32)
            {
                for (int i = header.Length; i < 32; i++)
                {
                    header += " "; //Append empty spaces until header is max length (32)
                }

                byte[] headerBytes = Encoding.ASCII.GetBytes(header + "|");

                T2SClientMessage clientMessage = (T2SClientMessage)MainWindow.ByteArrayToObject(recBuf);
                temp   = MainWindow.ObjectToByteArray(clientMessage);
                recBuf = new byte[temp.Length + headerBytes.Length];

                Array.Copy(headerBytes, recBuf, headerBytes.Length);
                Array.Copy(temp, 0, recBuf, 33, temp.Length);

                byte[] message = recBuf; //Append message with the header

                //Send to all connected sockets except self
                foreach (SocketPair s in clientSockets)
                {
                    if (s.socket != current)
                    {
                        s.socket.Send(message);
                    }
                }
                if (clientMessage.UpdateProfile)
                {
                    foreach (SocketPair s in clientSockets)
                    {
                        if (s.MacAddr == clientMessage.MacAddr)
                        {
                            s.ProfilePicture = (clientMessage.ProfilePicture == null) ? s.ProfilePicture : clientMessage.ProfilePicture;
                            s.Username       = clientMessage.Username;
                            break;
                        }
                    }
                }
                //If this is the first connection, we need to update our socketpair MacAddr for audit (also just send back to client)
                if (clientMessage.FirstConnect)
                {
                    Console.WriteLine("First connect: " + clientMessage.Username);
                    foreach (SocketPair s in clientSockets)
                    {
                        if (s.socket == current)
                        {
                            s.MacAddr        = clientMessage.MacAddr;
                            s.Username       = clientMessage.Username;
                            s.ProfilePicture = clientMessage.ProfilePicture;
                        }
                        else
                        {
                            T2SClientMessage otherClient = new T2SClientMessage()
                            {
                                FirstConnect   = true,
                                ProfilePicture = s.ProfilePicture,
                                Username       = s.Username,
                                MacAddr        = s.MacAddr
                            };
                            byte[] otherClientBuffer        = MainWindow.ObjectToByteArray(otherClient);
                            byte[] otherClientBufferMessage = new byte[otherClientBuffer.Length + 33]; //message to send; appends length of header
                            string otherClientHeader        = otherClientBuffer.Length.ToString();
                            for (int i = otherClientHeader.Length; i < 32; i++)
                            {
                                otherClientHeader += " "; //Append empty spaces until header is max length (32)
                            }
                            otherClientHeader += "|";

                            Array.Copy(Encoding.ASCII.GetBytes(otherClientHeader), otherClientBufferMessage, 33);
                            Array.Copy(otherClientBuffer, 0, otherClientBufferMessage, 33, otherClientBuffer.Length);

                            current.Send(otherClientBufferMessage);
                        }
                    }
                    current.Send(message); //Send the profile back to themself
                }
            }
            else
            {
                Console.WriteLine("HEADER TOO LARGE!!! Header length: " + header.Length);
            }
            current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
        }