/// <summary> /// Extract the first incoming packet. /// </summary> public bool ReceivePacket(out Buffer buffer, out IPEndPoint source) { if (Port == 0) { Stop(); throw new InvalidOperationException( "You must specify a non-zero port to UdpProtocol.Start() before you can receive data."); } if (inQueue.Count != 0) { lock (inQueue) { Datagram dg = inQueue.Dequeue(); buffer = dg.buffer; source = dg.ip; #if DEBUG Debug.Log("[UdpProtocol:ReceivePacket(" + buffer.size + ", " + source + ") - Receiving packet ...."); #endif if (OnPacketReceived != null) { OnPacketReceived.Invoke(buffer, source); } return(true); } } buffer = null; source = null; return(false); }
/// <summary> /// Handler for end of the begin receive call. /// </summary> /// <param name="ar">Contains the results of the receive.</param> private void EndReceiveFrom(IAsyncResult ar) { try { // When socket is closed the object will be disposed of in the middle of a receive. if (!m_isClosed) { EndPoint remoteEP = m_addressFamily == AddressFamily.InterNetwork ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); int bytesRead = m_udpSocket.EndReceiveFrom(ar, ref remoteEP); if (bytesRead > 0) { // During experiments IPPacketInformation wasn't getting set on Linux. Without it the local IP address // cannot be determined when a listener was bound to IPAddress.Any (or IPv6 equivalent). If the caller // is relying on getting the local IP address on Linux then something may fail. //if (packetInfo != null && packetInfo.Address != null) //{ // localEndPoint = new IPEndPoint(packetInfo.Address, localEndPoint.Port); //} byte[] packetBuffer = new byte[bytesRead]; Buffer.BlockCopy(m_recvBuffer, 0, packetBuffer, 0, bytesRead); OnPacketReceived?.Invoke(this, m_localPort, remoteEP as IPEndPoint, packetBuffer); } } } catch (SocketException) { // Socket errors do not trigger a close. The reason being that there are genuine situations that can cause them during // normal RTP operation. For example: // - the RTP connection may start sending before the remote socket starts listening, // - an on hold, transfer, etc. operation can change the RTP end point which could result in socket errors from the old // or new socket during the transition. // It also seems that once a UDP socket pair have exchanged packets and the remote party closes the socket exception will occur // in the BeginReceive method (very handy). Follow-up, this doesn't seem to be the case, the socket exception can occur in // BeginReceive before any packets have been exchanged. This means it's not safe to close if BeginReceive gets an ICMP // error since the remote party may not have initialised their socket yet. //logger.LogWarning($"SocketException UdpReceiver.EndReceiveMessage. {sockExcp}"); } catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored. { } catch (Exception excp) { Logger.Logger.Error($"Exception UdpReceiver.EndReceiveMessage. ->{excp}"); Close(excp.Message); } finally { if (!m_isClosed) { BeginReceiveFrom(); } } }
public virtual void ___recv___(Victem victem, string packet) { var handler = OnPacketReceived; if (handler != null) { OnPacketReceived?.Invoke(victem, packet); } }
/// <summary> /// Manuseia Comunicação do Cliente /// </summary> private void HandleClient(object obj) { try { //Recebe cliente a partir do parâmetro TcpClient tcpClient = (TcpClient)obj; NetworkStream clientStream = tcpClient.GetStream(); #region READ ON CONNECT INICIAL AuthPacket packet = ReceivePacket(clientStream); var client = new AuthClient(tcpClient) { Name = packet.Message.ServerName, Type = packet.Message.ServerType, Key = packet.Message.Key }; Clients.Add(client); ClientConnected(client); OnPacketReceived?.Invoke(client, packet); #endregion //Escuta contínuamente as mensagens dos clientes (Servidores) enquanto estiver conectado while (tcpClient.Connected) { try { packet = ReceivePacket(clientStream); OnPacketReceived?.Invoke(client, packet); } catch (Exception erro) { Console.WriteLine(DateTime.Now.ToString() + $" Exception error:" + Environment.NewLine); Console.WriteLine(erro.Message + Environment.NewLine); //Desconecta client DisconnectClient(client); } } //Caso o Client não estiver mais conectado DisconnectClient(client); } catch (Exception erro) { Console.WriteLine(DateTime.Now.ToString() + $" Exception error:" + Environment.NewLine); Console.WriteLine(erro.Message + Environment.NewLine); } }
private void InvokeDataReceivedEvent(Packet packet) { try { OnPacketReceived?.Invoke(packet.PacketPayload); } catch (Exception exception) { logger?.LogError(exception, "OnPacketReceived threw an exception"); } }
internal void HandlePacket(PosixTimeval timeval, TcpPacket tcp, TcpConnection connection) { OnPacketReceived?.Invoke(timeval, tcp, connection, this); // look for disconnection if (tcp.Finished == true) { IsOpen = false; OnFlowClosed?.Invoke(timeval, tcp, connection, this); } }
private void MonitorStreams() { while (IsRunning) { foreach (var client in Connections.ToList()) { if (!client.IsSocketConnected()) { var e5 = BuildEvent(client, null, String.Empty); Connections.Remove(client); OnConnectionRemoved?.Invoke(this, e5); continue; } if (client.Socket.Available != 0) { var readObject = ReadObject(client.Socket); var e1 = BuildEvent(client, null, readObject); OnPacketReceived?.Invoke(this, e1); if (readObject is PingPacket ping) { client.SendObject(ping).Wait(); continue; } if (readObject is PersonalPacket pp) { var destination = Connections.FirstOrDefault(c => c.ClientId.ToString() == pp.GuidId); var e4 = BuildEvent(client, destination, pp); OnPersonalPacketReceived?.Invoke(this, e4); if (destination != null) { destination.SendObject(pp).Wait(); var e2 = BuildEvent(client, destination, pp); OnPersonalPacketSent?.Invoke(this, e2); } } else { foreach (var c in Connections.ToList()) { c.SendObject(readObject).Wait(); var e3 = BuildEvent(client, c, readObject); OnPacketSent?.Invoke(this, e3); } } } } } }
/// <summary> /// Manuseia Comunicação do Cliente /// </summary> private void HandlePlayer(object obj) { //Recebe cliente a partir do parâmetro TcpClient tcpClient = (TcpClient)obj; var Player = OnConnectPlayer(tcpClient); var thread = new Thread(new ThreadStart(Player.RefreshData)); thread.Start(); //Chama evento OnClientConnected this.OnClientConnected?.Invoke(Player); while (Player.Connected) { try { byte[] message = ReceivePacket(tcpClient.GetStream()); if (message.Length >= 5) { if (Player.Connected) { var packet = new Packet(message, Player.GetKey); if (ShowLog) { packet.Log(); } //Dispara evento OnPacketReceived OnPacketReceived?.Invoke(Player, packet: packet); } } else { if (Player.Connected) { DisconnectPlayer(Player); } } } catch (Exception ex) { ServerExpection(Player, ex); } } if (Player.Connected) { DisconnectPlayer(Player); } }
private async Task Listen() { List <string> removeList = new List <string>(); for (int i = clients.Count - 1; i >= 0; i--) { Client client = clients[i]; if (client.IsAlive()) { Packet p = await client.Listen(); if (p != null) { PacketType type = p.GetPacketType(); if (type == PacketType.Identify) { OnUserConnect.Invoke(this, new UserConnectEventArgs(client)); } else { OnPacketReceived.Invoke(this, new PacketReceivedEventArgs(client, p)); } } } else { await client.Stop(); Logger.Info($"Client dropped [{client.GetSessionId()}]"); clients.RemoveAt(i); string sess = client.GetSessionId(); bool onlyone = true; for (int j = clients.Count - 1; j >= 0; j--) { if (clients[j].GetSessionId() == sess) { onlyone = false; break; } } if (onlyone) { OnUserDisconnect.Invoke(this, new UserDosconnectEventArgs(client)); } } } }
private void RecvThread() { while (Active) { try { var packet = Packet.FromStream(reader); OnPacketReceived?.Invoke(packet); } catch (Exception e) { Console.WriteLine(e); } } }
/// <summary> /// Handler for end of the begin receive call. /// </summary> /// <param name="ar">Contains the results of the receive.</param> private void EndReceiveMessageFrom(IAsyncResult ar) { try { // When socket is closed the object will be disposed of in the middle of a receive. if (!m_isClosed) { SocketFlags flags = SocketFlags.None; EndPoint remoteEP = (m_udpSocket.LocalEndPoint.AddressFamily == AddressFamily.InterNetwork) ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); int bytesRead = m_udpSocket.EndReceiveMessageFrom(ar, ref flags, ref remoteEP, out var packetInfo); if (bytesRead > 0) { IPEndPoint localEndPoint = new IPEndPoint(packetInfo.Address, (m_udpSocket.LocalEndPoint as IPEndPoint).Port); byte[] packetBuffer = new byte[bytesRead]; Buffer.BlockCopy(m_recvBuffer, 0, packetBuffer, 0, bytesRead); OnPacketReceived?.Invoke(this, localEndPoint, remoteEP as IPEndPoint, packetBuffer); } } } catch (SocketException) { // Socket errors do not trigger a close. The reason being that there are genuine situations that can cause them during // normal RTP operation. For example: // - the RTP connection may start sending before the remote socket starts listening, // - an on hold, transfer, etc. operation can change the RTP end point which could result in socket errors from the old // or new socket during the transition. // It also seems that once a UDP socket pair have exchanged packets and the remote party closes the socket exception will occur // in the BeginReceive method (very handy). Follow-up, this doesn't seem to be the case, the socket exception can occur in // BeginReceive before any packets have been exchanged. This means it's not safe to close if BeginReceive gets an ICMP // error since the remote party may not have initialised their socket yet. } catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored. { } catch (Exception excp) { logger.LogError($"Exception UdpReceiver.EndReceiveMessageFrom. {excp}"); Close(excp.Message); } finally { if (!m_isClosed) { BeginReceive(); } } }
private void OnDataReceived(IAsyncResult res) { IPEndPoint ip = new IPEndPoint(IPAddress.Any, ReceivePort); byte[] data = client.EndReceive(res, ref ip); UdpPacket packet = UdpPacket.ParseData(data); if (packet != null) { OnPacketReceived?.Invoke(packet); } else { Console.Out.WriteLine("Bad packet received."); } client.BeginReceive(new AsyncCallback(OnDataReceived), null); }
private void ReceiveLoop() { while (_alive) { int bytesRec = _socket.Receive(_buffer); if (_currentPacket == null) { _currentPacket = new Packet(); } if (_currentPacket.AddFragment(_buffer, bytesRec)) { OnPacketReceived?.Invoke((Packet)_currentPacket.Clone()); _currentPacket = null; } } }
/// <summary> /// Manuseia Comunicação do Cliente /// </summary> private void HandlePlayer(object obj) { //Recebe cliente a partir do parâmetro TcpClient tcpClient = (TcpClient)obj; var Player = OnConnectPlayer(tcpClient); //Chama evento OnClientConnected this.OnClientConnected?.Invoke(Player); while (Player.Connected) { try { byte[] message = ReceivePacket(tcpClient.GetStream()); if (message.Length >= 5) { if (Player.Connected) { Player.Server = this; //Dispara evento OnPacketReceived OnPacketReceived?.Invoke(Player, packet: new Packet(message, Player.GetKey)); } } else { if (Player.Connected) { DisconnectPlayer(Player); } } } catch { DisconnectPlayer(Player); } } if (Player.Connected) { DisconnectPlayer(Player); } }
/// <summary> /// Manuseia Comunicação do Cliente /// </summary> private void HandleClient(object obj) { //Recebe cliente a partir do parâmetro TcpClient tcpClient = (TcpClient)obj; NetworkStream clientStream = tcpClient.GetStream(); #region READ ON CONNECT INICIAL AuthPacket packet = ReceivePacket(clientStream); var client = new AuthClient(tcpClient, packet); Clients.Add(client); Console.Title = string.Format("Pangya Fresh Up! AuthServer - LOGIN: {0}, GAMES: {1}, MESSENGER: {2}", Clients.Model.Where(c => c.Data.Type == AuthClientTypeEnum.LoginServer).ToList().Count, Clients.Model.Where(c => c.Data.Type == AuthClientTypeEnum.GameServer).ToList().Count, Clients.Model.Where(c => c.Data.Type == AuthClientTypeEnum.MessengerServer).ToList().Count); ClientConnected(client); OnPacketReceived?.Invoke(client, packet); #endregion //Escuta contínuamente as mensagens dos clientes (Servidores) enquanto estiver conectado while (tcpClient.Connected) { try { packet = ReceivePacket(clientStream); OnPacketReceived?.Invoke(client, packet); } catch { //Desconecta client DisconnectClient(client); } } //Caso o Client não estiver mais conectado if (tcpClient.Connected) { DisconnectClient(client); } }
protected async Task Init() { // Get Info serverInfo = await rpc.ServerInfoAsync(new ServerInfoRequest()); // TCP relay tcpRelaySocket.OnPacketReceived += (buf, len) => { OnPacketReceived?.Invoke(buf, len); }; tcpRelaySocket.Init(); // Periodically restart listeners & reconnect PingTimer = new Timer(); PingTimer.Interval = 15000; PingTimer.Elapsed += PingServer; PingTimer.Start(); // Sync clients periodically Task.Run(SyncTask); }
private void HandlePacket(object obj) { //Recebe OnCliente a partir do parâmetro TcpClient tcpClient = (TcpClient)obj; var Player = OnConnectBot(tcpClient); //Chama evento OnClientConnected this.OnClientConnected?.Invoke(Player); while (Player.Tcp.Connected) { try { var messageBufferRead = new byte[500000]; //Tamanho do BUFFER á ler //Lê mensagem do OnCliente //size =500000; int bytesRead = Player.Tcp.GetStream().Read(messageBufferRead, 0, 500000); //variável para armazenar a mensagem recebida byte[] message = new byte[bytesRead]; //Copia mensagem recebida Buffer.BlockCopy(messageBufferRead, 0, message, 0, bytesRead); if (message.Length >= 5) { var packet = new ClientPacket(message); OnPacketReceived?.Invoke(Player, packet); } } catch (Exception ex) { OnException(Player, ex); } } }
public void Connect(IPEndPoint endPoint) { _peer.Start(); _listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod) => { var dataPacket = new DataPacket(dataReader.RawData, dataReader.UserDataOffset, dataReader.UserDataSize, ConvertDeliveryMethod(deliveryMethod)); OnPacketReceived?.Invoke(endPoint, dataPacket, dataReader.Recycle); }; _listener.PeerConnectedEvent += peer => { _serverPeer = peer; OnConnected?.Invoke(peer.EndPoint); }; _listener.PeerDisconnectedEvent += (peer, info) => { _serverPeer = null; using (var disconnectInfo = new LiteNetDisconnectInfo(info)) OnDisconnected?.Invoke(endPoint, disconnectInfo); }; _peer.Connect(endPoint.Address.ToString(), endPoint.Port, "SomeConnectionKey333"); }
private void HandleAuthClient() { //Inicia Thread KeepAlive var keepAliveThread = new Thread(new ThreadStart(KeepAlive)); keepAliveThread.Start(); while (Tcp.Connected) { try { var messageBufferRead = new byte[500000]; //Tamanho do BUFFER á ler //Lê mensagem do cliente var bytesRead = Tcp.GetStream().Read(messageBufferRead, 0, 500000); //variável para armazenar a mensagem recebida var message = new byte[bytesRead]; //Copia mensagem recebida Buffer.BlockCopy(messageBufferRead, 0, message, 0, bytesRead); var json = System.Text.Encoding.Default.GetString(message); var response = JsonConvert.DeserializeObject <AuthPacket>(json); //Dispara evento OnPacketReceived OnPacketReceived?.Invoke(this, response); } catch { OnDisconnect?.Invoke(); } } }
private void RecvThread() { byte[] recvBuf = new byte[4096]; while (connected) { // Read the udp pak header .. int read = 0; while (read < 2) { read += socket.Receive(recvBuf, read, 2, SocketFlags.None); } ushort pakSize = (ushort)((recvBuf[0] << 8) | recvBuf[1]); // << content size pakSize += RECV_HDR_SIZE; // Read the full packet while (read < pakSize) { read += socket.Receive(recvBuf, read, pakSize - read, SocketFlags.None); } // Handle packet OnPacketReceived?.Invoke(recvBuf, pakSize); } }
IEnumerator StartReading() { byte[] meta = new byte[sizeof(Int32)]; while (!cts.IsCancellationRequested) { while (!cts.IsCancellationRequested && stream.DataAvailable) { var bytesRead = stream.Read(meta, 0, meta.Length); if (bytesRead > 0) { var packetSize = BitConverter.ToInt32(meta, 0); byte[] data = new byte[packetSize]; var startIndex = 0; while (startIndex < packetSize && !cts.IsCancellationRequested) { bytesRead = stream.Read(data, startIndex, packetSize - startIndex); startIndex += bytesRead; } OnPacketReceived?.Invoke(System.Text.Encoding.ASCII.GetString(data)); } } yield return(new WaitForEndOfFrame()); } }
public void PacketReceived(NetworkEventArgs e) { OnPacketReceived?.Invoke(e); }
private void RecvThread() { while (Active) { try { var from = new IPEndPoint(0, 0); var recvBuffer = udpClient.Receive(ref from); if (recvBuffer == null || recvBuffer.Length == 0) { continue; } NetworkPacket packet = NetworkPacket.FromByteArray(recvBuffer); if ((packet.from != remoteId && packet.from != 0) || (packet.to != localId && packet.to != 0)) { continue; } switch (packet.packetType) { case PacketType.SYN: case PacketType.SYN_ACK: throw new InvalidOperationException(); case PacketType.FIN: SendRawPacket(new NetworkPacket() { packetType = PacketType.FIN, from = localId, to = remoteId }); Reset(); break; case PacketType.Raw: if (packet.channel != (byte)EStreamChannel.KEstreamChannelDiscovery) { throw new InvalidOperationException(); } TypedMessage msg = TypedMessage.FromByteArray(packet.payload); EStreamDiscoveryMessage msgType = (EStreamDiscoveryMessage)msg.messageType; switch (msgType) { case EStreamDiscoveryMessage.KEstreamDiscoveryPingRequest: msg.messageType = (byte)EStreamDiscoveryMessage.KEstreamDiscoveryPingResponse; SendRawPacket(new NetworkPacket() { packetType = PacketType.Raw, from = packet.to, to = packet.from, channel = (byte)EStreamChannel.KEstreamChannelDiscovery, payload = msg.ToByteArray() }); break; default: throw new InvalidOperationException(); } break; case PacketType.Reliable: case PacketType.ReliableFragment: case PacketType.Unreliable: case PacketType.UnreliableFragment: ChannelData channelData = channels.GetOrNew(packet.channel); if (!channelData.receiveQueue.ContainsKey(packet.seq)) { channelData.receiveQueue.Add(packet.seq, packet); if (packet.seq < channelData.remoteSeq) { Console.WriteLine("WARNING! Late packet " + packet.seq + " we are already at " + channelData.remoteSeq); } } else { Console.WriteLine("WARNING! Got a resend of " + packet.seq); } // TODO: Clear the recv queue ushort?lastValidPacketSeq = channelData.remoteSeq > 0 ? (ushort)(channelData.remoteSeq - 1) : (ushort?)null; bool droppedIncompletePacket = false; foreach (NetworkPacket firstPacket in channelData.receiveQueue.Values) { if (firstPacket.seq < channelData.remoteSeq) { continue; } if (firstPacket.packetType == PacketType.ReliableFragment || firstPacket.packetType == PacketType.UnreliableFragment) { continue; } // Check if the packet has all the fragments bool isComplete = true; for (ushort neededSeq = firstPacket.seq; neededSeq <= firstPacket.seq + firstPacket.fragment; ++neededSeq) { if (!channelData.receiveQueue.ContainsKey(neededSeq)) { isComplete = false; break; } else { lastValidPacketSeq = neededSeq; } } if (!isComplete) { // The packet is not yet fully complete if (firstPacket.packetType == PacketType.Unreliable) { droppedIncompletePacket = true; continue; // this is unreliable so check if maybe next packet is complete } else { break; // we cannot skip any packet on reliable transports } } if (channelData.remoteSeq != firstPacket.seq) { Console.WriteLine("WARNING! Dropping unreliable packets! Jump from " + channelData.remoteSeq + " to " + firstPacket.seq + (droppedIncompletePacket ? " (previous incomplete)" : "")); } // We have a complete packet, receive it List <NetworkPacket> reassembleList = new List <NetworkPacket>(); for (ushort seq = firstPacket.seq; seq <= firstPacket.seq + firstPacket.fragment; ++seq) { if (seq != firstPacket.seq) { if (firstPacket.packetType == PacketType.Reliable) { Debug.Assert(channelData.receiveQueue[seq].packetType == PacketType.ReliableFragment); } else if (firstPacket.packetType == PacketType.Unreliable) { Debug.Assert(channelData.receiveQueue[seq].packetType == PacketType.UnreliableFragment); } else { Debug.Assert(false); } } reassembleList.Add(channelData.receiveQueue[seq]); } DataPacket dataPacket = ReassembleDataPacket(reassembleList); try { OnPacketReceived?.Invoke(dataPacket); } catch (Exception e) { Console.WriteLine(e); } channelData.remoteSeq = (ushort)(firstPacket.seq + firstPacket.fragment + 1); } if ((packet.packetType == PacketType.Reliable || packet.packetType == PacketType.ReliableFragment) && lastValidPacketSeq.HasValue) { using (MemoryStream ms = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(ms)) { writer.Write(channelData.receiveQueue[lastValidPacketSeq.Value].timestamp); writer.Flush(); SendRawPacket(new NetworkPacket() { packetType = PacketType.ReliableACK, from = localId, to = remoteId, channel = packet.channel, seq = lastValidPacketSeq.Value, payload = ms.ToArray() }); } } break; case PacketType.ReliableACK: //Console.WriteLine("ACKed channel=" + packet.channel + ", seq=" + packet.seq); // TODO break; } } catch (SocketException) { } catch (Exception e) { Console.WriteLine(e); } } }
public void ProcessRecvQueue() { foreach (var cdata in _sequences) { RUDPConnectionData sq = cdata.Value; List <RUDPPacket> PacketsToRecv = new List <RUDPPacket>(); lock (sq.ReceivedPackets) PacketsToRecv.AddRange(sq.ReceivedPackets.OrderBy(x => x.Seq)); PacketsToRecv = PacketsToRecv.GroupBy(x => x.Seq).Select(g => g.First()).ToList(); for (int i = 0; i < PacketsToRecv.Count; i++) { RUDPPacket p = PacketsToRecv[i]; lock (sq.ReceivedPackets) sq.ReceivedPackets.Remove(p); if (p.Seq < sq.Remote) { continue; } if (p.Seq > sq.Remote) { sq.ReceivedPackets.Add(p); break; } Debug("RECV <- {0}: {1}", p.Src, p); if (p.Qty == 0) { sq.Remote++; if (p.Type == RUDPPacketType.SYN) { if (IsServer) { Send(p.Src, RUDPPacketType.SYN, RUDPPacketFlags.ACK); OnClientConnect?.Invoke(p.Src); } else if (p.Flags == RUDPPacketFlags.ACK) { State = ConnectionState.OPEN; OnConnected?.Invoke(p.Src); } continue; } OnPacketReceived?.Invoke(p); } else { // Multipacket! List <RUDPPacket> multiPackets = PacketsToRecv.Skip(i).Take(p.Qty).ToList(); if (multiPackets.Count == p.Qty) { Debug("MULTIPACKET {0}", p.Id); byte[] buf; using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) foreach (RUDPPacket mp in multiPackets) { bw.Write(mp.Data); Debug("RECV MP <- {0}: {1}", p.Src, mp); } buf = ms.ToArray(); } Debug("MULTIPACKET ID {0} DATA: {1}", p.Id, Encoding.ASCII.GetString(buf)); OnPacketReceived?.Invoke(new RUDPPacket() { ACK = p.ACK, Retransmit = p.Retransmit, Sent = p.Sent, Data = buf, Dst = p.Dst, Flags = p.Flags, Id = p.Id, Qty = p.Qty, Received = p.Received, Seq = p.Seq, Src = p.Src, Type = p.Type }); sq.Remote += p.Qty; i += p.Qty; } else { if (multiPackets.Count < p.Qty) { sq.ReceivedPackets.Add(p); break; } else { Debug("P.QTY > MULTIPACKETS.COUNT ({0} > {1})", p.Qty, multiPackets.Count); throw new Exception(); } } } } } }
/// <summary> /// Handler for end of the begin receive call. /// </summary> /// <param name="ar">Contains the results of the receive.</param> private void EndReceiveFrom(IAsyncResult ar) { try { // When socket is closed the object will be disposed of in the middle of a receive. if (!m_isClosed) { EndPoint remoteEP = m_addressFamily == AddressFamily.InterNetwork ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); int bytesRead = m_udpSocket.EndReceiveFrom(ar, ref remoteEP); if (bytesRead > 0) { // During experiments IPPacketInformation wasn't getting set on Linux. Without it the local IP address // cannot be determined when a listener was bound to IPAddress.Any (or IPv6 equivalent). If the caller // is relying on getting the local IP address on Linux then something may fail. //if (packetInfo != null && packetInfo.Address != null) //{ // localEndPoint = new IPEndPoint(packetInfo.Address, localEndPoint.Port); //} byte[] packetBuffer = new byte[bytesRead]; // TODO: When .NET Frmework support is dropped switch to using a slice instead of a copy. Buffer.BlockCopy(m_recvBuffer, 0, packetBuffer, 0, bytesRead); OnPacketReceived?.Invoke(this, m_localEndPoint.Port, remoteEP as IPEndPoint, packetBuffer); } } // If there is still data available it should be read now. This is more efficient than calling // BeginReceiveFrom which will incur the overheaed of creating the callback and then immediately firing it. // It also avoids the situation where if the application cannot keep up with the network then BeginReceiveFrom // will be called synchronously (if data is available it calls the callback method immediately) which can // create a very nasty stack. if (!m_isClosed && m_udpSocket.Available > 0) { EndPoint remoteEP = m_addressFamily == AddressFamily.InterNetwork ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); while (!m_isClosed && m_udpSocket.Available > 0) { int bytesReadSync = m_udpSocket.ReceiveFrom(m_recvBuffer, 0, m_recvBuffer.Length, SocketFlags.None, ref remoteEP); if (bytesReadSync > 0) { byte[] packetBufferSync = new byte[bytesReadSync]; // TODO: When .NET Frmework support is dropped switch to using a slice instead of a copy. Buffer.BlockCopy(m_recvBuffer, 0, packetBufferSync, 0, bytesReadSync); OnPacketReceived?.Invoke(this, m_localEndPoint.Port, remoteEP as IPEndPoint, packetBufferSync); } else { break; } } } } catch (SocketException resetSockExcp) when(resetSockExcp.SocketErrorCode == SocketError.ConnectionReset) { // Thrown when close is called on a socket from this end. Safe to ignore. } catch (SocketException sockExcp) { // Socket errors do not trigger a close. The reason being that there are genuine situations that can cause them during // normal RTP operation. For example: // - the RTP connection may start sending before the remote socket starts listening, // - an on hold, transfer, etc. operation can change the RTP end point which could result in socket errors from the old // or new socket during the transition. // It also seems that once a UDP socket pair have exchanged packets and the remote party closes the socket exception will occur // in the BeginReceive method (very handy). Follow-up, this doesn't seem to be the case, the socket exception can occur in // BeginReceive before any packets have been exchanged. This means it's not safe to close if BeginReceive gets an ICMP // error since the remote party may not have initialised their socket yet. logger.LogWarning($"SocketException UdpReceiver.EndReceiveFrom ({sockExcp.SocketErrorCode}). {sockExcp}"); } catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored. { } catch (Exception excp) { logger.LogError($"Exception UdpReceiver.EndReceiveFrom. {excp}"); Close(excp.Message); } finally { if (!m_isClosed) { BeginReceiveFrom(); } } }
void UpdateServer() { IPEndPoint Sender = null; if (ReceivePacket(ref Sender, out NetPacket Packet)) { NetWreckClient Cli = FindOrCreateClient(Sender); Packet.SetIsValid(Cli.OnPacketReceived(Timestamp(), Packet)); if (Packet.IsValid()) { Packet.Sender = Cli; switch (Cli.State) { case ClientState.Connecting: { if (OnClientConnecting != null) { OnClientConnecting(Cli, Packet); } else { AcceptConnection(Cli); } break; } case ClientState.Connected: { if (Packet.Type == PacketType.ConnectionRequest) { AcceptConnection(Cli); break; } OnPacketReceived?.Invoke(Packet); break; } case ClientState.Disconnected: { Disconnect(Cli); break; } default: throw new NotImplementedException(); } } else { DebugPrint("Dropping invalid packet 2"); } FreePacket(Packet); } NetWreckClient[] Clients = ServerClientList.ToArray(); foreach (var C in Clients) { double LastReceived = LastReceiveTime(C); if (LastReceived > 10000) { ServerClientList.Remove(C); } else if (LastReceived > 2000) { Disconnect(C); } else { C.HandleQueuedPackets(this); } } }
private void OnPacketReceivedInternal(string packet) { OnPacketReceived?.Invoke(packet); }
void UpdateClient() { if (ServerConnectionClient == null) { return; } if (ReceivePacket(ref ServerConnectionClient.SenderEndPoint, out NetPacket Packet)) { Packet.SetIsValid(ServerConnectionClient.OnPacketReceived(Timestamp(), Packet)); if (Packet.IsValid()) { Packet.Sender = ServerConnectionClient; switch (ServerConnectionClient.State) { case ClientState.Connecting: if (Packet.Type == PacketType.ConnectionAccept) { ServerConnectionClient.State = ClientState.Connected; OnClientConnected?.Invoke(ServerConnectionClient); break; } break; case ClientState.Connected: if (Packet.Type == PacketType.ConnectionAccept) { break; } if (Packet.Type == PacketType.Disconnect) { Disconnect(ServerConnectionClient); break; } OnPacketReceived?.Invoke(Packet); break; case ClientState.Disconnected: break; default: throw new NotImplementedException(); } } else { DebugPrint("Dropping invalid packet 2"); } FreePacket(Packet); } if (ServerConnectionClient.State == ClientState.Connecting) { // If last packet sent was more than half a second ago, try again if (LastSendTime(ServerConnectionClient) > 500) { NetPacket P = AllocPacket(); P.PacketNum = 0; P.Payload = new byte[0]; P.Type = PacketType.ConnectionRequest; SendPacket(P, ServerConnectionClient); FreePacket(P); } } else if (ServerConnectionClient.State == ClientState.Connected) { ServerConnectionClient.HandleQueuedPackets(this); } }
private void OnDataReceived(IAsyncResult iar) { SocketInfo socketInfo = (SocketInfo)iar.AsyncState; try { int received = socketInfo.Socket.EndReceive(iar); if (received == 0) { if (OnClientDisconnected != null) { OnClientDisconnected(this); } return; } socketInfo.Index += received; byte[] dataa = new byte[received]; Buffer.BlockCopy(socketInfo.DataBuffer, 0, dataa, 0, received); if (OnPacketReceived != null) { OnPacketReceived.Invoke(new PacketReader(dataa)); } //Console.WriteLine(BitConverter.ToString(dataa)); //Console.WriteLine(HexEncoding.ToStringFromAscii(dataa)); WaitForData(); /*if (socketInfo.Index == socketInfo.DataBuffer.Length) { * switch (socketInfo.State) { * case SocketInfo.StateEnum.Header: * PacketReader headerReader = new PacketReader(socketInfo.DataBuffer); * byte[] packetHeaderB = headerReader.ToArray(); * int packetHeader = headerReader.ReadInt(); * short packetLength = (short)MapleCrypto.getPacketLength(packetHeader); * if (!_RIV.checkPacket(packetHeader)) { * Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Packet check failed. Disconnecting client."); * this.Socket.Close(); * } * socketInfo.State = SocketInfo.StateEnum.Content; * socketInfo.DataBuffer = new byte[packetLength]; * socketInfo.Index = 0; * WaitForData(socketInfo); * break; * case SocketInfo.StateEnum.Content: * byte[] data = socketInfo.DataBuffer; * * _RIV.crypt(data); * MapleCustomEncryption.Decrypt(data); * * if (data.Length != 0 && OnPacketReceived != null) { * OnPacketReceived(new PacketReader(data)); * } * WaitForData(); * break; * } * } else { * Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Warning] Not enough data"); * WaitForData(socketInfo); * }*/ } catch (ObjectDisposedException) { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: Socket has been closed"); //Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: Socket has been closed"); } catch (SocketException se) { if (se.ErrorCode != 10054) { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + se); //Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + se); } } catch (Exception e) { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + e); //Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + e); } }
private unsafe void DeviceOnPacketArrival(object sender, CaptureEventArgs e) { var fullPacket = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); var packet = fullPacket.Extract <TcpPacket>(); if (!packet.Push) { return; // Only TCP PSH has actual data; ACK does not } var ipv4Info = fullPacket.Extract <IPv4Packet>(); var connection = new StringBuilder(ipv4Info.SourceAddress.ToString()) .Append(':') .Append(packet.SourcePort.ToString()) .Append("=>") .Append(ipv4Info.DestinationAddress) .Append(':') .Append(packet.DestinationPort.ToString()) .ToString(); // All FFXIV packets begin with a packet header... fixed(void *payload = &packet.PayloadData[0]) { var packetHeader = Marshal.PtrToStructure <PacketHeader>(new IntPtr(payload)); if (!IsMagical(packetHeader)) { return; } // ...possibly with a compressed payload, using var remainder = new UnmanagedMemoryStream( (byte *)payload + 40, packet.PayloadData.Length - 40, packet.PayloadData.Length * 2, FileAccess.ReadWrite); if (packetHeader.IsCompressed) { using var deflateStream = new DeflateStream(remainder, CompressionMode.Decompress); deflateStream.CopyTo(remainder); } // ...followed by one or more segment headers, var segmentPtr = remainder.PositionPointer; var segments = new List <Segment>(); for (var i = 0; i < packetHeader.SegmentCount; i++) { var segmentHeader = Marshal.PtrToStructure <SegmentHeader>(new IntPtr(segmentPtr)); // ...potentially with an IPC header and body. IpcHeader ipcHeader = null; var ipcData = new byte[0]; if (segmentHeader.Type == SegmentType.Ipc) { ipcHeader = Marshal.PtrToStructure <IpcHeader>(new IntPtr(segmentPtr + 16)); ipcData = new byte[segmentHeader.Size]; using var ipcDataStreamUnmanaged = new UnmanagedMemoryStream(segmentPtr + 32, segmentHeader.Size); using var ipcDataStream = new MemoryStream(ipcData, writable: true); ipcDataStreamUnmanaged.CopyTo(ipcDataStream); OnIpcMessageReceived?.Invoke(connection, new FFXIVIpcMessage(ipcHeader, ipcData)); segmentPtr += 16 + segmentHeader.Size; } segments.Add(new Segment(segmentHeader, ipcHeader, ipcData)); } OnPacketReceived?.Invoke(connection, new FFXIVPacket(packetHeader, segments)); } }