public static void ShellCallback(MessageBase msg, NetBuffer buff) { if(CallbackMapping.ContainsKey(msg.Id)) { CallbackMapping[msg.Id](buff, msg); } }
public void fireDataRecieved(NetClient client, NetBuffer buffer) { if (DataRecieved != null) { DataRecieved(client, buffer); } }
public static void StatusChangeHandler(NetClient client, NetBuffer buffer) { string status_msg = buffer.ReadString(); NetConnectionStatus status = (NetConnectionStatus)buffer.ReadByte(); if (status == NetConnectionStatus.Connected) { Console.WriteLine("Client: Connected"); Console.Write("Client: Starting IOS"); int i; for (i = 0; i < 10; i++) { Console.Write("."); Thread.Sleep(500); } Console.WriteLine(""); //Show the IOS Master form System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); System.Windows.Forms.Application.Run(new MasterForm()); } if (status == NetConnectionStatus.Disconnected) { Console.WriteLine("Client: Disconnected - " + status_msg); } }
public void Write(NetBuffer om) { if (MetaData == null) MetaData = "Null"; om.Write(MetaData); om.Write(Data.Length); om.Write(Data); }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); s_mainForm = new Form1(); WriteToConsole("Type 'connect <host> <port>' to connect to another peer, or 'connect <port>' to connect to another localhost peer"); NetConfiguration config = new NetConfiguration("p2pchat"); config.MaxConnections = 256; s_peer = new NetPeer(config); //s_peer.VerboseLog = true; s_peer.SetMessageTypeEnabled(NetMessageType.ConnectionRejected | NetMessageType.BadMessageReceived | NetMessageType.VerboseDebugMessage, true); // start listening for incoming connections s_peer.Start(); // create a buffer to read data into s_readBuffer = s_peer.CreateBuffer(); Application.Idle += new EventHandler(OnAppIdle); Application.Run(s_mainForm); s_peer.Shutdown("Application exiting"); }
private static void HandleMessage(NetMessageType type, NetConnection source, NetBuffer buffer) { switch (type) { case NetMessageType.DebugMessage: Console.WriteLine(buffer.ReadString()); break; case NetMessageType.StatusChanged: NetConnectionStatus status = source.Status; if (status == NetConnectionStatus.Connected) { source.Tag = ImageClientStatus.JustConnected; s_nextPixelToSend[source] = 0; } else if (status == NetConnectionStatus.Disconnected) { if (s_nextPixelToSend.ContainsKey(source)) s_nextPixelToSend.Remove(source); } break; case NetMessageType.Receipt: source.Tag = ImageClientStatus.Running; break; default: // unhandled break; } }
internal void DoSendDiscoveryRequest( IPEndPoint endPoint, bool useBroadcast, NetDiscoveryRequest request, float interval, float timeout) { if (!m_netBase.m_isBound) m_netBase.Start(); if (request == null) { m_netBase.LogVerbose("Creating discovery request " + m_nextRequestNumber); request = new NetDiscoveryRequest(endPoint, m_nextRequestNumber++, useBroadcast, interval, timeout); if (m_requests == null) m_requests = new List<NetDiscoveryRequest>(); m_requests.Add(request); } string appIdent = m_netBase.m_config.ApplicationIdentifier; NetBuffer data = new NetBuffer(appIdent.Length + 8); // write app identifier data.Write(appIdent); // write netbase identifier to avoid self-discovery data.Write(m_netBase.m_randomIdentifier); // write request number data.Write((ushort)request.Number); m_netBase.LogWrite("Discovering " + endPoint.ToString() + "..."); m_netBase.QueueSingleUnreliableSystemMessage(NetSystemType.Discovery, data, endPoint, useBroadcast); }
private static void HandleMessage(NetMessageType type, NetConnection source, NetBuffer buffer) { switch (type) { case NetMessageType.StatusChanged: if (source.LocalHailData == null) source.LocalHailData = Encoding.ASCII.GetBytes("Hi; I'm " + s_peer.GetHashCode()); if (source.RemoteHailData != null) WriteToConsole("New status: " + source.Status + " - remote hail is: " + Encoding.ASCII.GetString(source.RemoteHailData)); else WriteToConsole("New status: " + source.Status + " - remote hail is null"); break; case NetMessageType.DebugMessage: case NetMessageType.VerboseDebugMessage: case NetMessageType.BadMessageReceived: case NetMessageType.ConnectionRejected: WriteToConsole(buffer.ReadString()); break; case NetMessageType.Data: WriteToConsole(source.RemoteEndpoint + " writes: " + buffer.ReadString()); break; case NetMessageType.ServerDiscovered: // discovered another peer! s_peer.Connect(buffer.ReadIPEndPoint(), Encoding.ASCII.GetBytes("Hi; I'm " + s_peer.GetHashCode())); break; default: // unhandled break; } }
private static void HandleMessage(NetMessageType type, NetConnection source, NetBuffer buffer) { switch (type) { case NetMessageType.DebugMessage: WriteToConsole(buffer.ReadString()); break; case NetMessageType.StatusChanged: WriteToConsole("New status: " + source.Status + " (" + buffer.ReadString() + ")"); UpdateStatisticsDisplay(source); break; case NetMessageType.Data: //System.IO.File.AppendAllText("C:\\receivedpackets.txt", s_userMessagesReceived.ToString() + ": " + msg.ReadString() + " (" + msg.m_sequenceNumber + ")" + Environment.NewLine); s_userMessagesReceived++; // simulate some processing of the message here for (int i = 0; i < buffer.LengthBytes - 2; i++) buffer.ReadByte(); // check checksum ushort checksum = NetChecksum.Adler16(buffer.Data, 0, buffer.LengthBytes - 2); ushort given = buffer.ReadUInt16(); if (checksum != given) WriteToConsole("Wrong checksum! Expected " + checksum + " found given " + given); double b = s_userMessagesReceived; for (int i = 0; i < 1000; i++) b += Math.Sqrt((double)i) / Math.Sin(s_tmp); s_tmp += b / 10000.0; break; default: break; } }
public bool ReadMessage(NetBuffer intoBuffer, out NetMessageType type, out INetConnection sender) { NetConnection senderInternal; bool messageExists = _netServer.ReadMessage(intoBuffer, out type, out senderInternal); sender = new NetConnectionWrapper(senderInternal); return messageExists; }
bool ClientCommand(client_t cl, NetBuffer msg) { int seq = msg.ReadInt32(); string s = msg.ReadString(); // see if we have already executed it if (cl.lastClientCommand >= seq) return true; Common.Instance.WriteLine("ClientCommand: {0}[s{1}]: {2}", cl.name, seq, s); // drop the connection if we have somehow lost commands if (seq > cl.lastClientCommand + 1) { Common.Instance.WriteLine("Client {0} lost {1} clientCommands", cl.name, seq-cl.lastClientCommand+1); DropClient(cl, "Lost reliable commands"); return false; } // don't allow another command for one second cl.nextReliableTime = (int)time + 1000; ExecuteClientCommand(cl, s); cl.lastClientCommand = seq; cl.lastClientCommandString = s; return true; // continue procesing }
public static void Process(NetServer server, NetBuffer buffer, NetConnection sender) { Config config = Config.Instance; List<NetConnection> connections = server.Connections; //Lets send that message onto any plugin clients foreach (NetConnection connection in connections) { if (config.Server.client_connections.ContainsKey(connection.RemoteEndpoint.ToString())) { string client_type = (string)config.Server.client_connections[connection.RemoteEndpoint.ToString()]; if (client_type.ToLower() == "plugin") { string msg = buffer.ReadString(); Console.WriteLine("Slave: Data sent - " + msg); NetBuffer slavebuf = server.CreateBuffer(); slavebuf.Write(msg); server.SendMessage(slavebuf, connection, NetChannel.ReliableInOrder4); } } } }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); s_mainForm = new Form1(); NetConfiguration config = new NetConfiguration("stress"); config.ThrottleBytesPerSecond = 3500; s_client = new NetClient(config); // 100 ms simulated roundtrip latency s_client.SimulatedMinimumLatency = 0.1f; // ... + 0 to 50 ms s_client.SimulatedLatencyVariance = 0.05f; // 10% loss (!) // s_client.SimulatedLoss = 0.1f; // 5% duplicated messages (!) // s_client.SimulatedDuplicates = 0.05f; s_readBuffer = s_client.CreateBuffer(); s_sentUntil = NetTime.Now; s_nextDisplay = NetTime.Now; Application.Idle += new EventHandler(OnAppIdle); Application.Run(s_mainForm); s_client.Shutdown("Application exiting"); }
public void fireConnectionRejected(NetClient client, NetBuffer buffer) { if (ConnectionRejected != null) { ConnectionRejected(client, buffer); } }
protected NetBase(NetConfiguration config) { Debug.Assert(config != null, "Config must not be null"); if (string.IsNullOrEmpty(config.ApplicationIdentifier)) throw new ArgumentException("Must set ApplicationIdentifier in NetConfiguration!"); m_config = config; m_receiveBuffer = new NetBuffer(config.ReceiveBufferSize); m_sendBuffer = new NetBuffer(config.SendBufferSize); m_senderRemote = (EndPoint)new IPEndPoint(IPAddress.Any, 0); m_statistics = new NetBaseStatistics(); m_receivedMessages = new NetQueue<IncomingNetMessage>(4); m_scratchBuffer = new NetBuffer(32); m_bindLock = new object(); m_discovery = new NetDiscovery(this); m_randomIdentifier = new byte[8]; NetRandom.Instance.NextBytes(m_randomIdentifier); m_unsentOutOfBandMessages = new NetQueue<NetBuffer>(); m_unsentOutOfBandRecipients = new NetQueue<IPEndPoint>(); m_susmQueue = new Queue<SUSystemMessage>(); // default enabled message types m_enabledMessageTypes = NetMessageType.Data | NetMessageType.StatusChanged | NetMessageType.ServerDiscovered | NetMessageType.DebugMessage | NetMessageType.Receipt; }
private void receive() { NetBuffer buffer = new NetBuffer(); bool keepGoing = true; while (keepGoing) { NetIncomingMessage message; while ((message = client.ReadMessage()) != null) { switch (message.MessageType) { case NetIncomingMessageType.DebugMessage: Console.WriteLine(buffer.ReadString()); break; case NetIncomingMessageType.StatusChanged: Console.WriteLine("New status: " + client.Status + " (Reason: " + buffer.ReadString() + ")"); if(client.Status != NetPeerStatus.Running) { keepGoing = false; break; } break; case NetIncomingMessageType.Data: // Handle data in buffer here break; } } } }
public void fireClientApproval(NetServer server, NetBuffer buffer, NetConnection sender) { if (ClientApproval != null) { ClientApproval(server, buffer, sender); } }
public void fireDataRecieved(NetServer server, NetBuffer buffer, NetConnection sender) { if (DataRecieved != null) { DataRecieved(server, buffer, sender); } }
public void fireStatusChanged(NetServer server, NetBuffer buffer, NetConnection sender) { if (StatusChanged != null) { StatusChanged(server, buffer, sender); } }
/// <summary> /// Will overwrite any existing data /// </summary> public void CopyFrom(NetBuffer source) { int byteLength = source.LengthBytes; InternalEnsureBufferSize(byteLength * 8); Buffer.BlockCopy(source.Data, 0, Data, 0, byteLength); m_bitLength = source.m_bitLength; m_readPosition = 0; }
public void OnFightMessage(NetBuffer buff, MessageBase msg) { var im = buff as NetIncomingMessage; if (im != null) { FightMessageImpl(im, msg); } }
public override void Write(NetBuffer om) { base.Write(om); om.Write(FollowerId.Count); foreach(var obj in FollowerId) { om.Write(obj); } }
public void OnHireFollowerMessage(NetBuffer buff, MessageBase msg) { var im = buff as NetIncomingMessage; if(im != null) { HireFollowerMessageImpl(im, msg); } }
public void AddQueMsg(NetBuffer buff, NetChannel chan) { lock (Que) { Que.Add(new qmsg(buff, chan)); msgs++; } WH.Set(); }
public void OnLoginMessage(NetPeer client, NetBuffer buff, MessageBase msg) { var srv = client as NetClient; var im = buff as NetIncomingMessage; if (srv != null && im != null) { LoginResultMessageImpl(srv, im, msg); } }
public void Read(NetBuffer im) { MessagePacketId = im.ReadInt64(); Number = im.ReadInt32(); int length = im.ReadInt32(); if (length != 0) { Bytes = im.ReadBytes(length); } }
public TankAClient() { NetConfiguration netConfig = new NetConfiguration("TankA"); client = new NetClient(netConfig); readBuffer = client.CreateBuffer(); timeBetweenFireReq = Tank.MinTBF - 50; clientIndex = 1; }
public override void Write(NetBuffer om) { base.Write(om); om.Write(Followers.Count); foreach(var obj in Followers) { om.Write(obj.Key); om.Write(obj.Value); } }
public void Write(NetBuffer om) { if (Address == null) Address = string.Empty; if (ConnectName == null) ConnectName = string.Empty; if (Information == null) ConnectName = string.Empty; om.Write(Address); om.Write(ConnectName); om.Write(Information); }
public override void Read(NetBuffer im) { base.Read(im); int c = im.ReadInt32(); for(int i = 0; i < c; ++i) { int id = im.ReadInt32(); FollowerId.Add(id); } }
internal AppenderStream(NetBuffer netBuffer) { Buffer = netBuffer; }
internal override void HandleReceivedMessage(IncomingNetMessage message, IPEndPoint senderEndpoint) { double now = NetTime.Now; int payLen = message.m_data.LengthBytes; // NAT introduction? if (HandleNATIntroduction(message)) { return; } // Out of band? if (message.m_type == NetMessageLibraryType.OutOfBand) { if ((m_enabledMessageTypes & NetMessageType.OutOfBandData) != NetMessageType.OutOfBandData) { return; // drop } // just deliever message.m_msgType = NetMessageType.OutOfBandData; message.m_senderEndPoint = senderEndpoint; EnqueueReceivedMessage(message); return; } if (message.m_sender == null) { // // Handle unconnected message // // not a connected sender; only allow System messages if (message.m_type != NetMessageLibraryType.System) { if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Rejecting non-system message from unconnected source: " + message, null, message.m_senderEndPoint); } return; } // read type of system message NetSystemType sysType = (NetSystemType)message.m_data.ReadByte(); switch (sysType) { case NetSystemType.Connect: LogVerbose("Connection request received from " + senderEndpoint); // check app ident if (payLen < 4) { if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Malformed Connect message received from " + senderEndpoint, null, senderEndpoint); } return; } string appIdent = message.m_data.ReadString(); if (appIdent != m_config.ApplicationIdentifier) { if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Connect for different application identification received: " + appIdent, null, senderEndpoint); } return; } // read random identifer byte[] rnd = message.m_data.ReadBytes(8); if (NetUtility.CompareElements(rnd, m_randomIdentifier)) { // don't allow self-connect if ((m_enabledMessageTypes & NetMessageType.ConnectionRejected) == NetMessageType.ConnectionRejected) { NotifyApplication(NetMessageType.ConnectionRejected, "Connection to self not allowed", null, senderEndpoint); } return; } int bytesReadSoFar = (message.m_data.Position / 8); int hailLen = message.m_data.LengthBytes - bytesReadSoFar; byte[] hailData = null; if (hailLen > 0) { hailData = new byte[hailLen]; Buffer.BlockCopy(message.m_data.Data, bytesReadSoFar, hailData, 0, hailLen); } if (m_connections.Count >= m_config.m_maxConnections) { if ((m_enabledMessageTypes & NetMessageType.ConnectionRejected) == NetMessageType.ConnectionRejected) { NotifyApplication(NetMessageType.ConnectionRejected, "Server full; rejecting connect from " + senderEndpoint, null, senderEndpoint); } // send connection rejected NetBuffer rejreason = new NetBuffer("Server full"); QueueSingleUnreliableSystemMessage( NetSystemType.ConnectionRejected, rejreason, senderEndpoint, false ); return; } // Create connection LogWrite("New connection: " + senderEndpoint); NetConnection conn = new NetConnection(this, senderEndpoint, null, hailData); // Connection approval? if ((m_enabledMessageTypes & NetMessageType.ConnectionApproval) == NetMessageType.ConnectionApproval) { // Ask application if this connection is allowed to proceed IncomingNetMessage app = CreateIncomingMessage(); app.m_msgType = NetMessageType.ConnectionApproval; if (hailData != null) { app.m_data.Write(hailData); } app.m_sender = conn; conn.m_approved = false; EnqueueReceivedMessage(app); // Don't add connection; it's done as part of the approval procedure return; } // it's ok AddConnection(now, conn); break; case NetSystemType.ConnectionEstablished: if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Connection established received from non-connection! " + senderEndpoint, null, senderEndpoint); } return; case NetSystemType.Discovery: if (m_config.AnswerDiscoveryRequests) { m_discovery.HandleRequest(message, senderEndpoint); } break; case NetSystemType.DiscoveryResponse: if (m_allowOutgoingConnections) { // NetPeer IncomingNetMessage resMsg = m_discovery.HandleResponse(message, senderEndpoint); if (resMsg != null) { resMsg.m_senderEndPoint = senderEndpoint; EnqueueReceivedMessage(resMsg); } } break; default: if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Undefined behaviour for " + this + " receiving system type " + sysType + ": " + message + " from unconnected source", null, senderEndpoint); } break; } // done return; } // ok, we have a sender if (message.m_type == NetMessageLibraryType.Acknowledge) { message.m_sender.HandleAckMessage(message); return; } if (message.m_type == NetMessageLibraryType.System) { // // Handle system messages from connected source // if (payLen < 1) { if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Received malformed system message; payload length less than 1 byte", null, senderEndpoint); } return; } NetSystemType sysType = (NetSystemType)message.m_data.ReadByte(); switch (sysType) { case NetSystemType.Connect: case NetSystemType.ConnectionEstablished: case NetSystemType.Ping: case NetSystemType.Pong: case NetSystemType.Disconnect: case NetSystemType.ConnectionRejected: case NetSystemType.StringTableAck: message.m_sender.HandleSystemMessage(message, now); break; case NetSystemType.ConnectResponse: if (m_allowOutgoingConnections) { message.m_sender.HandleSystemMessage(message, now); } else { if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Undefined behaviour for server and system type " + sysType, null, senderEndpoint); } } break; case NetSystemType.Discovery: // Allow discovery even if connected if (m_config.AnswerDiscoveryRequests) { m_discovery.HandleRequest(message, senderEndpoint); } break; default: if ((m_enabledMessageTypes & NetMessageType.BadMessageReceived) == NetMessageType.BadMessageReceived) { NotifyApplication(NetMessageType.BadMessageReceived, "Undefined behaviour for server and system type " + sysType, null, senderEndpoint); } break; } return; } message.m_sender.HandleUserMessage(message); }
public NetBuffer(NetBuffer buffer) { Data = buffer.Data; m_readPosition = buffer.m_readPosition; m_bitLength = buffer.m_readPosition; }
public NetBuffer(NetBuffer buffer, int lengthBits) { Data = buffer.Data; m_readPosition = buffer.m_readPosition; m_bitLength = m_readPosition + lengthBits; }
//public static void WriteMessageToRemotePlayer(NetPeer peer, GameOptions gameOpts) //{ // byte[] serializedGameOptions; // MemoryStream ms = new MemoryStream(); // BinaryFormatter bf1 = new BinaryFormatter(); // bf1.Serialize(ms, gameOpts); // serializedGameOptions = ms.ToArray(); // NetBuffer buffer = new NetBuffer(serializedGameOptions); // peer.SendToAll(buffer, NetChannel.ReliableInOrder1); //} public static void WriteMessageToRemotePlayer(NetPeer peer, String msg) { Lidgren.Network.NetBuffer buff = new Lidgren.Network.NetBuffer(); buff.Write(msg); peer.SendToAll(buff, Lidgren.Network.NetChannel.ReliableInOrder1); }
/// <summary> /// Queue a reliable message for sending. When it has arrived ReceiptReceived will be fired on owning NetBase, and the ReceiptEventArgs will contain the object passed to this method. /// </summary> public void SendMessage(NetBuffer data, NetChannel channel, NetBuffer receiptData) { SendMessage(data, channel, receiptData, false); }
// TODO: Use this with TRUE isLibraryThread for internal sendings (acks etc) internal void SendMessage(NetBuffer data, NetChannel channel, NetBuffer receiptData, bool isLibraryThread) { if (m_status != NetConnectionStatus.Connected) { throw new NetException("Status must be Connected to send messages"); } if (data.LengthBytes > m_owner.m_config.m_maximumTransmissionUnit) { // // Fragmented message // int dataLen = data.LengthBytes; int chunkSize = m_owner.m_config.m_maximumTransmissionUnit - 10; // header int numFragments = dataLen / chunkSize; if (chunkSize * numFragments < dataLen) { numFragments++; } ushort fragId = m_nextSendFragmentId++; for (int i = 0; i < numFragments; i++) { OutgoingNetMessage fmsg = m_owner.CreateOutgoingMessage(); fmsg.m_type = NetMessageLibraryType.UserFragmented; fmsg.m_msgType = NetMessageType.Data; NetBuffer fragBuf = m_owner.CreateBuffer(); fragBuf.Write(fragId); fragBuf.WriteVariableUInt32((uint)i); fragBuf.WriteVariableUInt32((uint)numFragments); if (i < numFragments - 1) { // normal fragment fragBuf.Write(data.Data, i * chunkSize, chunkSize); } else { // last fragment int bitsInLast = data.LengthBits - (chunkSize * (numFragments - 1) * 8); int bytesInLast = dataLen - (chunkSize * (numFragments - 1)); fragBuf.Write(data.Data, i * chunkSize, bytesInLast); // add receipt only to last message fmsg.m_receiptData = receiptData; } fmsg.m_data = fragBuf; fmsg.m_data.m_refCount = 1; // since it's just been created fmsg.m_numSent = 0; fmsg.m_nextResend = double.MaxValue; fmsg.m_sequenceChannel = channel; fmsg.m_sequenceNumber = -1; if (isLibraryThread) { m_unsentMessages.Enqueue(fmsg); } else { lock (m_lockedUnsentMessages) m_lockedUnsentMessages.Enqueue(fmsg); } } // TODO: recycle the original, unfragmented data return; } // // Normal, unfragmented, message // OutgoingNetMessage msg = m_owner.CreateOutgoingMessage(); msg.m_msgType = NetMessageType.Data; msg.m_type = NetMessageLibraryType.User; msg.m_data = data; msg.m_data.m_refCount++; // it could have been sent earlier also msg.m_numSent = 0; msg.m_nextResend = double.MaxValue; msg.m_sequenceChannel = channel; msg.m_sequenceNumber = -1; msg.m_receiptData = receiptData; if (isLibraryThread) { m_unsentMessages.Enqueue(msg); } else { lock (m_lockedUnsentMessages) m_lockedUnsentMessages.Enqueue(msg); } }
internal void SendUnsentMessages(double now) { // Add any acknowledges to unsent messages if (m_acknowledgesToSend.Count > 0) { if (m_unsentMessages.Count < 1) { // Wait before sending acknowledges? if (m_ackMaxDelayTime > 0.0f) { if (m_ackWithholdingStarted == 0.0) { m_ackWithholdingStarted = now; } else { if (now - m_ackWithholdingStarted < m_ackMaxDelayTime) { return; // don't send (only) acks just yet } // send acks "explicitly" ie. without any other message being sent m_ackWithholdingStarted = 0.0; } } } // create ack messages and add to m_unsentMessages CreateAckMessages(); } if (m_unsentMessages.Count < 1) { return; } // throttling float throttle = m_owner.m_config.ThrottleBytesPerSecond; float maxSendBytes = float.MaxValue; if (throttle > 0) { double frameLength = now - m_lastSentUnsentMessages; //int wasDebt = (int)m_throttleDebt; if (m_throttleDebt > 0) { m_throttleDebt -= (float)(frameLength * (double)m_owner.m_config.ThrottleBytesPerSecond); } //int nowDebt = (int)m_throttleDebt; //if (nowDebt != wasDebt) // LogWrite("THROTTLE worked off -" + (nowDebt - wasDebt) + " bytes = " + m_throttleDebt); m_lastSentUnsentMessages = now; maxSendBytes = throttle - m_throttleDebt; if (maxSendBytes < 0) { return; // throttling; no bytes allowed to be sent } } int mtu = m_owner.Configuration.MaximumTransmissionUnit; int messagesInPacket = 0; NetBuffer sendBuffer = m_owner.m_sendBuffer; sendBuffer.Reset(); while (m_unsentMessages.Count > 0) { OutgoingNetMessage msg = m_unsentMessages.Peek(); int estimatedMessageSize = msg.m_data.LengthBytes + 5; // check if this message fits the throttle window if (estimatedMessageSize > maxSendBytes) // TODO: Allow at last one message if no debt { break; } // need to send packet and start a new one? if (messagesInPacket > 0 && sendBuffer.LengthBytes + estimatedMessageSize > mtu) { m_owner.SendPacket(m_remoteEndPoint); int sendLen = sendBuffer.LengthBytes; m_statistics.CountPacketSent(sendLen); //LogWrite("THROTTLE Send packet +" + sendLen + " bytes = " + m_throttleDebt + " (maxSendBytes " + maxSendBytes + " estimated " + estimatedMessageSize + ")"); m_throttleDebt += sendLen; sendBuffer.Reset(); } if (msg.m_sequenceNumber == -1) { AssignSequenceNumber(msg); } // pop and encode message m_unsentMessages.Dequeue(); int pre = sendBuffer.m_bitLength; msg.m_data.m_readPosition = 0; msg.Encode(sendBuffer); int encLen = (sendBuffer.m_bitLength - pre) / 8; m_statistics.CountMessageSent(msg, encLen); maxSendBytes -= encLen; if (msg.m_sequenceChannel >= NetChannel.ReliableUnordered) { // reliable; store message (incl. buffer) msg.m_numSent++; StoreMessage(now, msg); } else { // not reliable, don't store - recycle... NetBuffer b = msg.m_data; b.m_refCount--; msg.m_data = null; // ... unless someone else is using the buffer if (b.m_refCount <= 0) { m_owner.RecycleBuffer(b); } //m_owner.m_messagePool.Push(msg); } messagesInPacket++; } // send current packet if (messagesInPacket > 0) { m_owner.SendPacket(m_remoteEndPoint); int sendLen = sendBuffer.LengthBytes; m_statistics.CountPacketSent(sendLen); //LogWrite("THROTTLE Send packet +" + sendLen + " bytes = " + m_throttleDebt); m_throttleDebt += sendLen; } }
/* * /// <summary> * /// Read any received message in any connection queue * /// </summary> * public NetBuffer ReadMessage(out NetConnection sender) * { * if (m_receivedMessages.Count < 1) * { * sender = null; * return null; * } * * NetMessage msg = m_receivedMessages.Dequeue(); * sender = msg.m_sender; * * NetBuffer retval = msg.m_data; * msg.m_data = null; * m_messagePool.Push(msg); * * Debug.Assert(retval.Position == 0); * * return retval; * } */ /// <summary> /// Read any received message in any connection queue /// </summary> public bool ReadMessage( NetBuffer intoBuffer, IList <NetConnection> onlyFor, bool includeNullConnectionMessages, out NetMessageType type, out NetConnection sender) { if (m_receivedMessages.Count < 1) { sender = null; type = NetMessageType.None; m_dataReceivedEvent.Reset(); return(false); } IncomingNetMessage msg = null; lock (m_receivedMessages) { int sz = m_receivedMessages.Count; for (int i = 0; i < sz; i++) { msg = m_receivedMessages.Peek(i); if (msg != null) { if ((msg.m_sender == null && includeNullConnectionMessages) || onlyFor.Contains(msg.m_sender)) { m_receivedMessages.Dequeue(i); break; } msg = null; } } } if (msg == null) { sender = null; type = NetMessageType.None; return(false); } sender = msg.m_sender; // recycle NetMessage object NetBuffer content = msg.m_data; msg.m_data = null; type = msg.m_msgType; // m_messagePool.Push(msg); Debug.Assert(content.Position == 0); // swap content of buffers byte[] tmp = intoBuffer.Data; intoBuffer.Data = content.Data; content.Data = tmp; // set correct values for returning value (ignore the other, it's being recycled anyway) intoBuffer.m_bitLength = content.m_bitLength; intoBuffer.m_readPosition = 0; // recycle NetBuffer object (incl. old intoBuffer byte array) RecycleBuffer(content); return(true); }
/// <summary> /// Read any received message in any connection queue /// </summary> public bool ReadMessage(NetBuffer intoBuffer, out NetMessageType type, out NetConnection sender) { IPEndPoint senderEndPoint; return(ReadMessage(intoBuffer, out type, out sender, out senderEndPoint)); }
/// <summary> /// Read any received message in any connection queue /// </summary> public bool ReadMessage( NetBuffer intoBuffer, out NetMessageType type, out NetConnection sender, out IPEndPoint senderEndPoint) { if (intoBuffer == null) { throw new ArgumentNullException("intoBuffer"); } if (m_receivedMessages.Count < 1) { sender = null; senderEndPoint = null; type = NetMessageType.None; m_dataReceivedEvent.Reset(); return(false); } IncomingNetMessage msg; lock (m_receivedMessages) msg = m_receivedMessages.Dequeue(); if (msg == null) { sender = null; type = NetMessageType.None; senderEndPoint = null; return(false); } #if DEBUG if (msg.m_data == null) { throw new NetException("Ouch, no data!"); } if (msg.m_data.Position != 0) { throw new NetException("Ouch, stale data!"); } #endif senderEndPoint = msg.m_senderEndPoint; sender = msg.m_sender; intoBuffer.Tag = msg.m_data.Tag; // // recycle NetMessage object and NetBuffer // NetBuffer content = msg.m_data; msg.m_data = null; type = msg.m_msgType; // swap content of buffers byte[] tmp = intoBuffer.Data; intoBuffer.Data = content.Data; if (tmp == null) { tmp = new byte[8]; // application must have lost it somehow } content.Data = tmp; // set correct values for returning value (ignore the other, it's being recycled anyway) intoBuffer.m_bitLength = content.m_bitLength; intoBuffer.m_readPosition = 0; // recycle message // m_messagePool.Push(msg); // recycle buffer RecycleBuffer(content); return(true); }
/// <summary> /// Queue message for sending /// </summary> public void SendMessage(NetBuffer data, NetChannel channel) { SendMessage(data, channel, null, false); }
protected override void Dispose(bool _) => Buffer = null;
protected WrapperStream(NetBuffer netBuffer, in int start, int length, bool isReadMode)