예제 #1
0
        private void StartReceive(string bindIp)
        {
            _socket = CreateSocket(bindIp);

            var thread = new Thread(async() =>
            {
                while (!_isDisposing)
                {
                    try
                    {
                        //Start receiving data
                        ArraySegment <byte> buff = new ArraySegment <byte>(new byte[2500]);
                        var end = new IPEndPoint(IPAddress.Any, 0);
                        SocketReceiveFromResult v = await _socket.ReceiveFromAsync(buff, SocketFlags.None, end);

                        AtemServerConnection conn = _connections.FindOrCreateConnection(v.RemoteEndPoint, CurrentVersion, out _);
                        if (conn == null)
                        {
                            continue;
                        }

                        byte[] buffer = buff.Array;
                        var packet    = new ReceivedPacket(buffer);

                        if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.Handshake))
                        {
                            conn.ResetConnStatsInfo();
                            // send handshake back
                            byte[] test =
                            {
                                buffer[0], buffer[1], // flags + length
                                buffer[2], buffer[3], // session id
                                0x00, 0x00,           // acked pkt id
                                0x00, 0x00,           // retransmit request
                                buffer[8], buffer[9], // unknown2
                                0x00, 0x00,           // server pkt id
                                0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
                            };

                            var sendThread = new Thread(o =>
                            {
                                while (!conn.HasTimedOut)
                                {
                                    conn.TrySendQueued(_socket);
                                    Task.Delay(3).Wait();
                                }
                            });
                            sendThread.Start();

                            await _socket.SendToAsync(new ArraySegment <byte>(test, 0, 20), SocketFlags.None,
                                                      v.RemoteEndPoint);

                            continue;
                        }

                        if (!conn.IsOpened)
                        {
                            conn.OnReceivePacket += (sender, pkt) =>
                            {
                                if (ActiveConnectionId == conn.Id)
                                {
                                    lock (PendingPackets)
                                    {
                                        // Queue the packets for parsing and processing in the main thread
                                        PendingPackets.Add(pkt);
                                        HasPendingPackets.Set();
                                    }
                                }
                            };
                            var recvThread = new Thread(o =>
                            {
                                while (!conn.HasTimedOut || conn.HasCommandsToProcess)
                                {
                                    // We dont want this, but we dont want this to build up and be a memory leak
                                    conn.GetNextCommands();

                                    //conn.HandleInner(_state, connection, cmds);
                                }
                            });
                            recvThread.Start();
                        }

                        conn.Receive(_socket, packet);

                        if (conn.ReadyForData)
                        {
                            QueueDataDumps(conn);
                        }
                    }
                    catch (SocketException)
                    {
                        // Reinit the socket as it is now unavailable
                        //_socket = CreateSocket();
                    }
                    catch (ObjectDisposedException)
                    {
                        // Normal part of shutdown
                        break;
                    }
                }

                // Notify finished
                _receiveRunning.Set();
            });

            thread.Start();
        }
예제 #2
0
 public static void ProcessPacket(NPacket packet)
 {
     PendingPackets.Enqueue(packet);
 }