// unsequenced packets only, returns number of bytes sent internal int SendSingleMessageAtOnce(NetMessage msg, NetConnection connection, IPEndPoint endpoint) { m_sendBuffer.ResetWritePointer(); msg.Encode(connection, m_sendBuffer); if (connection != null) { return(ExecuteSend(m_sendBuffer, connection, connection.RemoteEndpoint)); } else { return(ExecuteSend(m_sendBuffer, null, endpoint)); } }
public void DiscoverLocalServers(int serverPort) { IPEndPoint broadcast = new IPEndPoint(IPAddress.Broadcast, serverPort); NetMessage msg = NetDiscovery.EncodeRequest(this); Log.Info("Broadcasting server discovery ping..."); // special send style; can't use simulated lag due to socket options try { m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); m_sendBuffer.ResetWritePointer(); msg.Encode(null, m_sendBuffer); int bytesSent = m_socket.SendTo(m_sendBuffer.Data, 0, m_sendBuffer.LengthBytes, SocketFlags.None, broadcast); Log.Verbose(string.Format(CultureInfo.InvariantCulture, "Sent {0} bytes to {1}", bytesSent, broadcast)); return; } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.ConnectionReset || sex.SocketErrorCode == SocketError.ConnectionRefused || sex.SocketErrorCode == SocketError.ConnectionAborted) { Log.Warning("Remote socket forcefully closed: " + sex.SocketErrorCode); return; } Log.Warning("Execute SocketException: " + sex.SocketErrorCode); return; } finally { m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); } }
internal void SendUnsentMessages(bool forceAcks, double frameLength) { if (m_unsentMessages.Count < 1 && !forceAcks) { if (m_status == NetConnectionStatus.Disconnecting) { SetStatus(NetConnectionStatus.Disconnected, m_pendingDisconnectedReason); } return; // nothing to send } //if (m_unsentMessages.Count < 1 && forceAcks) // m_parent.Log.Debug("FORCING EXPLICIT ACK"); float sendBytesAllowed = (float)frameLength * (float)Configuration.ThrottleBytesPerSecond; if (m_throttleDebt > sendBytesAllowed) { // NetBase.CurrentContext.Log.Debug("Working off debt: " + m_throttleDebt + " bytes by " + sendBytesAllowed"); m_throttleDebt -= sendBytesAllowed; return; } else if (m_throttleDebt > 0) { sendBytesAllowed -= m_throttleDebt; m_throttleDebt = 0; } NetBuffer sendBuffer = m_parent.m_sendBuffer; sendBuffer.ResetWritePointer(); int mtu = m_parent.Configuration.MaximumTransmissionUnit; float now = (float)NetTime.Now; int pktMsgAdded = 0; int ackMsgAdded = 0; int usrMsgAdded = 0; NetMessage msg; // TODO: make ack bitfield if possible while (m_unsentAcknowledges.Count > 0 && sendBytesAllowed > 0) { msg = m_unsentAcknowledges.Dequeue(); m_reusedAckMessage.SequenceChannel = msg.SequenceChannel; m_reusedAckMessage.SequenceNumber = msg.SequenceNumber; if (sendBuffer.LengthBytes + 3 > mtu) { // send buffer m_parent.ExecuteSend(sendBuffer, this, m_remoteEndpoint); sendBytesAllowed -= sendBuffer.LengthBytes; Statistics.PacketsSent++; Statistics.MessagesSent += pktMsgAdded; Statistics.AckMessagesSent += ackMsgAdded; Statistics.BytesSent += sendBuffer.LengthBytes; sendBuffer.ResetWritePointer(); pktMsgAdded = 0; ackMsgAdded = 0; } //m_parent.Log.Debug("Sending ack " + msg.SequenceChannel + "|" + msg.SequenceNumber); m_reusedAckMessage.Encode(this, sendBuffer); pktMsgAdded++; ackMsgAdded++; } // no unsent acks left! m_forceExplicitAckTime = 0.0; while (m_unsentMessages.Count > 0 && sendBytesAllowed > 0) { msg = m_unsentMessages.Dequeue(); // make pessimistic estimate of message length int estMsgLen = msg.EstimateEncodedLength(); if (sendBuffer.LengthBytes + estMsgLen > mtu) { if (pktMsgAdded < 1) { throw new NetException("Message too large to send: " + estMsgLen + " bytes: " + msg); } // send buffer m_parent.ExecuteSend(sendBuffer, this, m_remoteEndpoint); sendBytesAllowed -= sendBuffer.LengthBytes; Statistics.PacketsSent++; Statistics.MessagesSent += pktMsgAdded; Statistics.UserMessagesSent += usrMsgAdded; Statistics.AckMessagesSent += ackMsgAdded; Statistics.BytesSent += sendBuffer.LengthBytes; sendBuffer.ResetWritePointer(); pktMsgAdded = 0; ackMsgAdded = 0; } msg.Encode(this, sendBuffer); if (msg.m_type == NetMessageType.User || msg.m_type == NetMessageType.UserFragmented) { usrMsgAdded++; } pktMsgAdded++; // store until acknowledged if (msg.SequenceChannel >= NetChannel.ReliableUnordered) { float nextResend = now + (msg.m_numResends < 1 ? Configuration.ResendFirstUnacknowledgedDelay : Configuration.ResendSubsequentUnacknowledgedDelay); msg.m_nextResendTime = nextResend; //m_parent.Log.Debug("Storing " + msg.SequenceChannel + "|" + msg.SequenceNumber + " @ " + now + " first resend: " + nextResend); int seqChan = (int)msg.SequenceChannel; if (m_savedReliableMessages[seqChan] == null) { m_savedReliableMessages[seqChan] = new List <NetMessage>(); } m_savedReliableMessages[seqChan].Add(msg); } } if (pktMsgAdded > 0) { m_parent.ExecuteSend(sendBuffer, this, m_remoteEndpoint); sendBytesAllowed -= sendBuffer.LengthBytes; Statistics.PacketsSent++; Statistics.MessagesSent += pktMsgAdded; Statistics.UserMessagesSent += usrMsgAdded; Statistics.AckMessagesSent += ackMsgAdded; Statistics.BytesSent += sendBuffer.LengthBytes; } Debug.Assert(m_throttleDebt == 0); if (sendBytesAllowed < 0) { m_throttleDebt = -sendBytesAllowed; } }
// unsequenced packets only, returns number of bytes sent internal int SendSingleMessageAtOnce(NetMessage msg, NetConnection connection, IPEndPoint endpoint) { m_sendBuffer.ResetWritePointer(); msg.Encode(connection, m_sendBuffer); if (connection != null) return ExecuteSend(m_sendBuffer, connection, connection.RemoteEndpoint); else return ExecuteSend(m_sendBuffer, null, endpoint); }