public bool Receive(ref ReceivedSmartPacket receivedPacket) { bool haveResult = false; var packet = new ReceivedPacket(); while (true) { if (SubSock.Receive(ref packet)) { try { haveResult = OnReceive(packet.Buffer, packet.Offset, packet.Length, packet.EndPoint, ref receivedPacket); } catch (Exception) { haveResult = false; _buffersPool.Put(packet.Buffer); } } else { break; } if (haveResult) { break; } } return(haveResult); }
public bool Receive(ref ReceivedSmartPacket receivedPacket) { lock (_syncObject) { return(_socket.Receive(ref receivedPacket)); } }
public bool Receive(ref ReceivedSmartPacket receivedPacket) { if (_recvQueue.Count > 0) { receivedPacket = _recvQueue.Take(); return(true); } return(false); }
private void IOLoop() { bool active = false; while (!_closing) { lock (_syncObject) { _socket.Tick(); } SmartPacketToSend packetToSend = new SmartPacketToSend(); if (_sendQueue.Count > 0) { active = true; packetToSend = _sendQueue.Take(); lock (_syncObject) { _socket.Send(packetToSend.EndPoint, packetToSend.Buffer, packetToSend.Offset, packetToSend.Length, packetToSend.Reliable); } if (packetToSend.PutBufferToPool) { _buffersPool.Put(packetToSend.Buffer); } } ReceivedSmartPacket receivedPacket = new ReceivedSmartPacket(); bool received; lock (_syncObject) { received = _socket.Receive(ref receivedPacket); } if (received) { active = true; _recvQueue.Add(receivedPacket); } if (!active) { Thread.Sleep(10); } } }
private void IOLoop() { while (!_closing) { try { bool active = false; _socket.Tick(); State = _socket.State; SmartPacketToSend packetToSend = new SmartPacketToSend(); if (_sendQueue.Count > 0) { active = true; packetToSend = _sendQueue.Take(); _socket.Send(packetToSend.EndPoint, packetToSend.Buffer, packetToSend.Offset, packetToSend.Length, packetToSend.Reliable); if (packetToSend.PutBufferToPool) { _buffersPool.Put(packetToSend.Buffer); } } ReceivedSmartPacket receivedPacket = new ReceivedSmartPacket(); if (_socket.Receive(ref receivedPacket)) { active = true; _recvQueue.Add(receivedPacket); } if (!active) { Thread.Sleep(10); } } catch (Exception) { _closing = true; } } _socket.Close(); State = PixocketState.NotConnected; }
public bool Receive(ref ReceivedSmartPacket receivedPacket) { bool haveResult = false; var packet = new ReceivedPacket(); while (true) { try { packet.EndPoint = null; if (SubSock.Receive(ref packet)) { try { haveResult = OnReceive(packet.Buffer, packet.Offset, packet.Length, packet.EndPoint, ref receivedPacket); } catch (SocketException) { haveResult = false; _buffersPool.Put(packet.Buffer); if (packet.EndPoint != null && _seqStates.ContainsKey(packet.EndPoint)) { Close(packet.EndPoint, _seqStates[packet.EndPoint]); } } } else { break; } } catch (SocketException) { Close(); } if (haveResult) { break; } } return(haveResult); }
public bool CombineIfFull(PacketHeader header, IPEndPoint endPoint, ref ReceivedSmartPacket receivedPacket) { int fullLength = 0; // TODO: validate that headers of all fragments match var frag = GetFragmentedPacket(header); if (frag.Buffers.Count < header.FragCount) { return(false); } var buffersCount = frag.FragCount; for (int i = 0; i < buffersCount; ++i) { fullLength += frag.Buffers[i].Length; } byte[] combinedBuffer = _buffersPool.Get(fullLength); var targetOffset = 0; for (int i = 0; i < buffersCount; ++i) { var srcBuffer = frag.Buffers[i]; Array.Copy(srcBuffer.Buffer, srcBuffer.Offset, combinedBuffer, targetOffset, srcBuffer.Length); targetOffset += frag.Buffers[i].Length; _buffersPool.Put(srcBuffer.Buffer); } // TODO: optimize? _frags.Remove(frag); _fragPacketsPool.Put(frag); // TODO: calculate it? bool inOrder = true; receivedPacket.Buffer = combinedBuffer; receivedPacket.Offset = 0; receivedPacket.Length = fullLength; receivedPacket.EndPoint = endPoint; receivedPacket.InOrder = inOrder; return(true); }
private bool OnReceiveFragment(byte[] buffer, int offset, int length, IPEndPoint endPoint, PacketHeader header, ref ReceivedSmartPacket receivedPacket) { var seqState = GetSeqStateOnReceive(endPoint, header); seqState.AddFragment(buffer, offset, length, header); return(seqState.CombineIfFull(header, endPoint, ref receivedPacket)); }
private bool OnReceiveComplete(byte[] buffer, int offset, int length, IPEndPoint endPoint, PacketHeader header, bool inOrder, ref ReceivedSmartPacket receivedPacket) { var headerLen = header.HeaderLength; var payloadLength = length - headerLen; if (payloadLength > 0) { receivedPacket.Buffer = buffer; receivedPacket.Offset = offset + headerLen; receivedPacket.Length = payloadLength; receivedPacket.EndPoint = endPoint; receivedPacket.InOrder = inOrder; return(true); } return(false); }
private bool OnReceive(byte[] buffer, int offset, int length, IPEndPoint endPoint, ref ReceivedSmartPacket receivedPacket) { bool haveResult = false; var header = _headersPool.Get(); header.Init(buffer, offset); var seqState = GetSeqStateOnReceive(endPoint, header); if (length != header.Length || seqState == null) { // Wrong packet _headersPool.Put(header); _buffersPool.Put(buffer); return(false); } // Update activity timestamp on receive packet seqState.LastActive = Environment.TickCount; if (seqState.CheckConnected()) { // Send response only for request if (header.SessionId == PacketHeader.EmptySessionId) { SendConnectionResponse(endPoint, seqState); } _callbacks.OnConnect(endPoint); } else if (header.SessionId == PacketHeader.EmptySessionId && (header.Flags & PacketHeader.Connect) != 0) { SendConnectionResponse(endPoint, seqState); } if (!seqState.IsConnected) { // Wrong packet _headersPool.Put(header); _buffersPool.Put(buffer); return(false); } if ((header.Flags & PacketHeader.ContainsFrag) != 0) { bool isDuplicate = seqState.IsDuplicate(header.SeqNum); if (!isDuplicate) { haveResult = OnReceiveFragment(buffer, offset, length, endPoint, header, ref receivedPacket); seqState.RegisterIncoming(header.SeqNum); } } else if ((header.Flags & PacketHeader.ContainsSeq) != 0) { bool isDuplicate = seqState.IsDuplicate(header.SeqNum); if (!isDuplicate) { bool inOrder = seqState.IsInOrder(header.SeqNum); haveResult = OnReceiveComplete(buffer, offset, length, endPoint, header, inOrder, ref receivedPacket); seqState.RegisterIncoming(header.SeqNum); } } if ((header.Flags & PacketHeader.Disconnect) != 0) { // Disconnect request received, send response if (!seqState.DisconnectRequestSent) { SendDisconnectPacket(endPoint, seqState); } _callbacks.OnDisconnect(endPoint, DisconnectReason.InitiatedByPeer); _seqStates.Remove(endPoint); _seqStatesPool.Put(seqState); } if ((header.Flags & PacketHeader.ContainsAck) != 0) { seqState.ReceiveAck(header.Acks); } if ((header.Flags & PacketHeader.NeedsAck) != 0) { seqState.EnqueueAck(header.SeqNum); } if (!haveResult && (header.Flags & PacketHeader.ContainsFrag) == 0) { _buffersPool.Put(buffer); } _headersPool.Put(header); return(haveResult); }