Example #1
0
        static void RecvCallback(object sender, SocketAsyncEventArgs e)
        {
            TcpSocket s = (TcpSocket)e.UserToken;

            if (s.Disconnected)
            {
                return;
            }

            try {
                // If received 0, means socket was closed
                int recvLen = e.BytesTransferred;
                if (recvLen == 0)
                {
                    s.Disconnect(); return;
                }

                s.HandleReceived(s.recvBuffer, recvLen);
                if (!s.Disconnected)
                {
                    s.ReceiveNextAsync();
                }
            } catch (SocketException) {
                s.Disconnect();
            } catch (ObjectDisposedException) {
                // Socket was closed by another thread, mark as disconnected
            } catch (Exception ex) {
                Logger.LogError(ex);
                s.Disconnect();
            }
        }
Example #2
0
        static void SendCallback(object sender, SocketAsyncEventArgs e)
        {
            TcpSocket s = (TcpSocket)e.UserToken;

            try {
                // TODO: Need to check if all data was sent or not?
                int sent = e.BytesTransferred;
                lock (s.sendLock) {
                    s.sendInProgress = false;

                    while (s.sendQueue.Count > 0)
                    {
                        // DoSendAsync returns false if SendAsync completed sync
                        // If that happens, SendCallback isn't called so we need to send data here instead
                        s.sendInProgress = s.TrySendAsync(s.sendQueue.Dequeue());

                        if (s.sendInProgress)
                        {
                            return;
                        }
                        if (s.Disconnected)
                        {
                            s.sendQueue.Clear();
                        }
                    }
                }
            } catch (SocketException) {
                s.Disconnect();
            } catch (ObjectDisposedException) {
                // Socket was already closed by another thread
            } catch (Exception ex) {
                Logger.LogError(ex);
            }
        }
Example #3
0
        static void SendCallback(object sender, SocketAsyncEventArgs e)
        {
            TcpSocket s = (TcpSocket)e.UserToken;

            try {
                lock (s.sendLock) {
                    // check if last packet was only partially sent
                    for (;;)
                    {
                        int sent  = e.BytesTransferred;
                        int count = e.Count;
                        if (sent >= count || sent <= 0)
                        {
                            break;
                        }

                        // last packet was only partially sent - resend rest of packet
                        s.sendArgs.SetBuffer(e.Offset + sent, e.Count - sent);
                        s.sendInProgress = s.socket.SendAsync(s.sendArgs);
                        if (s.sendInProgress)
                        {
                            return;
                        }
                    }

                    s.sendInProgress = false;
                    while (s.sendQueue.Count > 0)
                    {
                        // DoSendAsync returns false if SendAsync completed sync
                        // If that happens, SendCallback isn't called so we need to send data here instead
                        s.sendInProgress = s.TrySendAsync(s.sendQueue.Dequeue());

                        if (s.sendInProgress)
                        {
                            return;
                        }
                        if (s.Disconnected)
                        {
                            s.sendQueue.Clear();
                        }
                    }
                }
            } catch (SocketException) {
                s.Disconnect();
            } catch (ObjectDisposedException) {
                // Socket was already closed by another thread
            } catch (Exception ex) {
                Logger.LogError(ex);
            }
        }
Example #4
0
        static void AcceptCallback(IAsyncResult result)
        {
            if (Server.shuttingDown)
            {
                return;
            }
            TcpListen listen = (TcpListen)result.AsyncState;
            TcpSocket s      = null;

            try {
                Socket raw    = listen.socket.EndAccept(result);
                bool   cancel = false;

                OnConnectionReceivedEvent.Call(raw, ref cancel);
                if (cancel)
                {
                    // intentionally non-clean connection close
                    try { raw.Close(); } catch { }
                }
                else
                {
                    s = new TcpSocket(raw);
                    Logger.Log(LogType.UserActivity, s.IP + " connected to the server.");
                    s.Init();
                }
            } catch (Exception ex) {
                if (!(ex is SocketException))
                {
                    Logger.LogError(ex);
                }
                if (s != null)
                {
                    s.Close();
                }
            }
            listen.AcceptNextAsync();
        }
Example #5
0
        static void RecvCallback(object sender, SocketAsyncEventArgs e)
        {
            Player p = null;

            try {
                TcpSocket s = (TcpSocket)e.UserToken;
                p = s.player;
                if (p.disconnected)
                {
                    return;
                }

                int recvLen = e.BytesTransferred;
                if (recvLen == 0)
                {
                    p.Disconnect(); return;
                }

                // Packets may not always be fully received in a Receive call
                // As such, we may need to retain a little bit of partial packet data
                Buffer.BlockCopy(s.recvBuffer, 0, s.unprocessed, s.unprocessedLen, recvLen);
                s.unprocessedLen += recvLen;
                int processedLen = p.ProcessReceived(s.unprocessed, s.unprocessedLen);

                // Disconnect invalid clients
                if (p.nonPlayerClient && processedLen == -1)
                {
                    s.Close(); p.disconnected = true;
                }
                if (processedLen == -1)
                {
                    return;
                }

                // move remaining partial packet data back to start of unprocessed buffer
                for (int i = processedLen; i < s.unprocessedLen; i++)
                {
                    s.unprocessed[i - processedLen] = s.unprocessed[i];
                }
                s.unprocessedLen -= processedLen;

                if (!p.disconnected)
                {
                    s.ReceiveNextAsync();
                }
            } catch (SocketException) {
                if (p != null)
                {
                    p.Disconnect();
                }
            }  catch (ObjectDisposedException) {
                // Socket was closed by another thread, mark as disconnected
                if (p == null)
                {
                    return;
                }
                Player.connections.Remove(p);
                p.RemoveFromPending();
                p.disconnected = true;
            } catch (Exception ex) {
                Logger.LogError(ex);
                if (p != null)
                {
                    p.Leave("Error!");
                }
            }
        }