public AtemServerConnection FindOrCreateConnection(EndPoint ep, ProtocolVersion version, out bool isNew) { lock (connections) { AtemServerConnection val; if (connections.TryGetValue(ep, out val)) { isNew = false; return(val); } val = new AtemServerConnection(ep, 0x8008, version, OrderedConnections.Count); connections[ep] = val; OrderedConnections.Add(val); val.OnDisconnect += RemoveTimedOut; Log.InfoFormat("New connection from {0}", ep); isNew = true; return(val); } }
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(); }