public void OnException(NetException exception) { }
public void TestScenario() { var peer = TestHelper.CreatePeer(); NetOutgoingMessage msg = peer.CreateMessage(); msg.Write(false); msg.Write(-3, 6); msg.Write(42); msg.Write("duke of earl"); msg.Write((byte)43); msg.Write((ushort)44); msg.Write(UInt64.MaxValue, 64); msg.Write(true); msg.WritePadBits(); int bcnt = 0; msg.Write(567845.0f); msg.WriteVariableInt32(2115998022); msg.Write(46.0); msg.Write((ushort)14, 9); bcnt += msg.WriteVariableInt32(-47); msg.WriteVariableInt32(470000); msg.WriteVariableUInt32(48); bcnt += msg.WriteVariableInt64(-49); if (bcnt != 2) { throw new NetException("WriteVariable* wrote too many bytes!"); } byte[] data = msg.Data; NetIncomingMessage inc = TestHelper.CreateIncomingMessage(data, msg.LengthBits); StringBuilder bdr = new StringBuilder(); bdr.Append(inc.ReadBoolean()); bdr.Append(inc.ReadInt32(6)); bdr.Append(inc.ReadInt32()); string strResult; bool ok = inc.ReadString(out strResult); if (ok == false) { throw new NetException("Read/write failure"); } bdr.Append(strResult); bdr.Append(inc.ReadByte()); if (inc.PeekUInt16() != (ushort)44) { throw new NetException("Read/write failure"); } bdr.Append(inc.ReadUInt16()); if (inc.PeekUInt64(64) != UInt64.MaxValue) { throw new NetException("Read/write failure"); } bdr.Append(inc.ReadUInt64()); bdr.Append(inc.ReadBoolean()); inc.SkipPadBits(); bdr.Append(inc.ReadSingle()); bdr.Append(inc.ReadVariableInt32()); bdr.Append(inc.ReadDouble()); bdr.Append(inc.ReadUInt32(9)); bdr.Append(inc.ReadVariableInt32()); bdr.Append(inc.ReadVariableInt32()); bdr.Append(inc.ReadVariableUInt32()); bdr.Append(inc.ReadVariableInt64()); if (bdr.ToString().Equals("False-342duke of earl434418446744073709551615True56784521159980224614-4747000048-49")) { Console.WriteLine("Read/write tests OK"); } else { throw new NetException("Read/write tests FAILED!"); } msg = peer.CreateMessage(); NetOutgoingMessage tmp = peer.CreateMessage(); tmp.Write((int)42, 14); msg.Write(tmp); msg.Write(tmp); if (msg.LengthBits != tmp.LengthBits * 2) { throw new NetException("NetOutgoingMessage.Write(NetOutgoingMessage) failed!"); } tmp = peer.CreateMessage(); Test test = new Test(); test.Number = 42; test.Name = "Hallon"; test.Age = 8.2f; tmp.WriteAllFields(test, BindingFlags.Public | BindingFlags.Instance); data = tmp.Data; inc = TestHelper.CreateIncomingMessage(data, tmp.LengthBits); Test readTest = new Test(); inc.ReadAllFields(readTest, BindingFlags.Public | BindingFlags.Instance); NetException.Assert(readTest.Number == 42); NetException.Assert(readTest.Name == "Hallon"); NetException.Assert(readTest.Age == 8.2f); // test aligned WriteBytes/ReadBytes msg = peer.CreateMessage(); byte[] tmparr = new byte[] { 5, 6, 7, 8, 9 }; msg.Write(tmparr); inc = TestHelper.CreateIncomingMessage(msg.Data, msg.LengthBits); byte[] result = inc.ReadBytes(tmparr.Length); for (int i = 0; i < tmparr.Length; i++) { if (tmparr[i] != result[i]) { throw new Exception("readbytes fail"); } } }
internal void Exception(Exception e) => NetException?.Invoke(this, e);
public override void Perform() { NetException ex = _exception as NetException; SocketError? errorCode = null; if (ex == null) { SocketException se = _exception as SocketException; if (se == null) { MsgBox.Error("Sorry,connection failed,please try again"); } } else { errorCode = ex.SocketError; } if (errorCode.HasValue) { if (errorCode == SocketError.Success) { if (ex.Message.Trim() != "Success") { if (ex.Message.Contains("asyncResult")) { return; } if (ex.Message == "HostUnreachable") { MsgBox.Warning("Host unreachable"); } else if (ex.Message == "TimedOut") { MsgBox.Warning("Unable to connect – connection timed out after multiple attempts"); } else if (ex.Message == "ConnectionRefused") { MsgBox.Warning("Connection refused"); } else { MsgBox.Warning(ex.Message); } } return; } if (IsCancel) { IsCancel = false; return; } if (errorCode.Value.ToString().Contains("asyncResult")) { return; } if (errorCode.Value.ToString() == "HostUnreachable") { MsgBox.Warning("Host unreachable"); } else if (errorCode.Value.ToString() == "TimedOut") { MsgBox.Warning("Unable to connect – connection timed out after multiple attempts"); } else if (ex.Message == "ConnectionRefused") { MsgBox.Warning("Connection Refused"); } else if (errorCode.Value.ToString() == "AddressNotAvailable") { MsgBox.Warning("Address or port is not available."); } else { MsgBox.Warning(errorCode.Value.ToString()); } switch (errorCode.Value) { case SocketError.AccessDenied: break; case SocketError.AddressNotAvailable: case SocketError.HostNotFound: case SocketError.HostUnreachable: break; case SocketError.NetworkDown: case SocketError.NetworkUnreachable: break; case SocketError.Shutdown: break; case SocketError.TooManyOpenSockets: break; } } }
internal override void ReceiveMessage(NetIncomingMessage message) { int relate = NetUtility.RelativeSequenceNumber(message.m_sequenceNumber, m_windowStart); // ack no matter what m_connection.QueueAck(message.m_receivedMessageType, message.m_sequenceNumber); if (relate == 0) { // Log("Received message #" + message.SequenceNumber + " right on time"); // // excellent, right on time // //m_peer.LogVerbose("Received RIGHT-ON-TIME " + message); AdvanceWindow(); m_peer.ReleaseMessage(message); // release withheld messages int nextSeqNr = (message.m_sequenceNumber + 1) % NetConstants.NumSequenceNumbers; while (m_earlyReceived[nextSeqNr % m_windowSize]) { message = m_withheldMessages[nextSeqNr % m_windowSize]; NetException.Assert(message != null); // remove it from withheld messages m_withheldMessages[nextSeqNr % m_windowSize] = null; m_peer.LogVerbose("Releasing withheld message #" + message); m_peer.ReleaseMessage(message); AdvanceWindow(); nextSeqNr++; } return; } if (relate < 0) { // duplicate m_connection.m_statistics.MessageDropped(); m_peer.LogVerbose("Received message #" + message.m_sequenceNumber + " DROPPING DUPLICATE"); return; } // relate > 0 = early message if (relate > m_windowSize) { // too early message! m_connection.m_statistics.MessageDropped(); m_peer.LogDebug("Received " + message + " TOO EARLY! Expected " + m_windowStart); return; } m_earlyReceived.Set(message.m_sequenceNumber % m_windowSize, true); m_peer.LogVerbose("Received " + message + " WITHHOLDING, waiting for " + m_windowStart); m_withheldMessages[message.m_sequenceNumber % m_windowSize] = message; }
internal void Heartbeat(double now, uint frameCounter) { m_peer.VerifyNetworkThread(); NetException.Assert(m_status != NetConnectionStatus.InitiatedConnect && m_status != NetConnectionStatus.RespondedConnect); if ((frameCounter % m_infrequentEventsSkipFrames) == 0) { if (now > m_timeoutDeadline) { // // connection timed out // m_peer.LogVerbose("Connection timed out at " + now + " deadline was " + m_timeoutDeadline); ExecuteDisconnect("Connection timed out", true); return; } // send ping? if (m_status == NetConnectionStatus.Connected) { if (now > m_sentPingTime + m_peer.m_configuration.m_pingInterval) { SendPing(); } // handle expand mtu MTUExpansionHeartbeat(now); } if (m_disconnectRequested) { ExecuteDisconnect(m_disconnectMessage, m_disconnectReqSendBye); return; } } bool connectionReset; // TODO: handle connection reset // // Note: at this point m_sendBufferWritePtr and m_sendBufferNumMessages may be non-null; resends may already be queued up // byte[] sendBuffer = m_peer.m_sendBuffer; int mtu = m_currentMTU; if ((frameCounter % m_messageCoalesceFrames) == 0) // coalesce a few frames { // // send ack messages // while (m_queuedOutgoingAcks.Count > 0) { int acks = (mtu - (m_sendBufferWritePtr + 5)) / 3; // 3 bytes per actual ack if (acks > m_queuedOutgoingAcks.Count) { acks = m_queuedOutgoingAcks.Count; } NetException.Assert(acks > 0); m_sendBufferNumMessages++; // write acks header sendBuffer[m_sendBufferWritePtr++] = (byte)NetMessageType.Acknowledge; sendBuffer[m_sendBufferWritePtr++] = 0; // no sequence number sendBuffer[m_sendBufferWritePtr++] = 0; // no sequence number int len = (acks * 3) * 8; // bits sendBuffer[m_sendBufferWritePtr++] = (byte)len; sendBuffer[m_sendBufferWritePtr++] = (byte)(len >> 8); // write acks for (int i = 0; i < acks; i++) { NetTuple <NetMessageType, int> tuple; m_queuedOutgoingAcks.TryDequeue(out tuple); //m_peer.LogVerbose("Sending ack for " + tuple.Item1 + "#" + tuple.Item2); sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item1; sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item2; sendBuffer[m_sendBufferWritePtr++] = (byte)(tuple.Item2 >> 8); } if (m_queuedOutgoingAcks.Count > 0) { // send packet and go for another round of acks NetException.Assert(m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0); m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndPoint, m_sendBufferNumMessages, out connectionReset); m_statistics.PacketSent(m_sendBufferWritePtr, 1); m_sendBufferWritePtr = 0; m_sendBufferNumMessages = 0; } } // // Parse incoming acks (may trigger resends) // NetTuple <NetMessageType, int> incAck; while (m_queuedIncomingAcks.TryDequeue(out incAck)) { //m_peer.LogVerbose("Received ack for " + acktp + "#" + seqNr); NetSenderChannelBase chan = m_sendChannels[(int)incAck.Item1 - 1]; // If we haven't sent a message on this channel there is no reason to ack it if (chan == null) { continue; } chan.ReceiveAcknowledge(now, incAck.Item2); } } // // send queued messages // if (m_peer.m_executeFlushSendQueue) { for (int i = m_sendChannels.Length - 1; i >= 0; i--) // Reverse order so reliable messages are sent first { var channel = m_sendChannels[i]; NetException.Assert(m_sendBufferWritePtr < 1 || m_sendBufferNumMessages > 0); if (channel != null) { channel.SendQueuedMessages(now); if (channel.NeedToSendMessages()) { m_peer.m_needFlushSendQueue = true; // failed to send all queued sends; likely a full window - need to try again } } NetException.Assert(m_sendBufferWritePtr < 1 || m_sendBufferNumMessages > 0); } } // // Put on wire data has been written to send buffer but not yet sent // if (m_sendBufferWritePtr > 0) { m_peer.VerifyNetworkThread(); NetException.Assert(m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0); m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndPoint, m_sendBufferNumMessages, out connectionReset); m_statistics.PacketSent(m_sendBufferWritePtr, m_sendBufferNumMessages); m_sendBufferWritePtr = 0; m_sendBufferNumMessages = 0; } }
public static void Run(NetPeer peer) { NetOutgoingMessage msg = peer.CreateMessage(); msg.Write(false); msg.Write(-3, 6); msg.Write(42); msg.Write("duke of earl"); msg.Write((byte)43); msg.Write((ushort)44); msg.Write(true); msg.WritePadBits(); int bcnt = 0; msg.Write(45.0f); msg.Write(46.0); bcnt += msg.WriteVariableInt32(-47); msg.WriteVariableInt32(470000); msg.WriteVariableUInt32(48); bcnt += msg.WriteVariableInt64(-49); if (bcnt != 2) { throw new NetException("WriteVariable* wrote too many bytes!"); } byte[] data = msg.PeekDataBuffer(); NetIncomingMessage inc = Program.CreateIncomingMessage(data, msg.LengthBits); StringBuilder bdr = new StringBuilder(); bdr.Append(inc.ReadBoolean()); bdr.Append(inc.ReadInt32(6)); bdr.Append(inc.ReadInt32()); bdr.Append(inc.ReadString()); bdr.Append(inc.ReadByte()); if (inc.PeekUInt16() != (ushort)44) { throw new NetException("Read/write failure"); } bdr.Append(inc.ReadUInt16()); bdr.Append(inc.ReadBoolean()); inc.SkipPadBits(); bdr.Append(inc.ReadSingle()); bdr.Append(inc.ReadDouble()); bdr.Append(inc.ReadVariableInt32()); bdr.Append(inc.ReadVariableInt32()); bdr.Append(inc.ReadVariableUInt32()); bdr.Append(inc.ReadVariableInt64()); if (bdr.ToString().Equals("False-342duke of earl4344True4546-4747000048-49")) { Console.WriteLine("Read/write tests OK"); } else { throw new NetException("Read/write tests FAILED!"); } msg = peer.CreateMessage(); NetOutgoingMessage tmp = peer.CreateMessage(); tmp.Write((int)42, 14); msg.Write(tmp); msg.Write(tmp); if (msg.LengthBits != tmp.LengthBits * 2) { throw new NetException("NetOutgoingMessage.Write(NetOutgoingMessage) failed!"); } tmp = peer.CreateMessage(); Test test = new Test(); test.Number = 42; test.Name = "Hallon"; test.Age = 8.2f; tmp.WriteAllFields(test, BindingFlags.Public | BindingFlags.Instance); data = tmp.PeekDataBuffer(); inc = Program.CreateIncomingMessage(data, tmp.LengthBits); Test readTest = new Test(); inc.ReadAllFields(readTest, BindingFlags.Public | BindingFlags.Instance); NetException.Assert(readTest.Number == 42); NetException.Assert(readTest.Name == "Hallon"); NetException.Assert(readTest.Age == 8.2f); // test aligned WriteBytes/ReadBytes msg = peer.CreateMessage(); byte[] tmparr = new byte[] { 5, 6, 7, 8, 9 }; msg.Write(tmparr); inc = Program.CreateIncomingMessage(msg.PeekDataBuffer(), msg.LengthBits); byte[] result = inc.ReadBytes(tmparr.Length); for (int i = 0; i < tmparr.Length; i++) { if (tmparr[i] != result[i]) { throw new Exception("readbytes fail"); } } }