Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increased KCP Fragments #35

Closed
wants to merge 10 commits into from
4 changes: 2 additions & 2 deletions kcp2k/Assets/kcp2k/highlevel/KcpConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public abstract class KcpConnection
// best for performance (use that one for batching!)
static int ReliableMaxMessageSize_Unconstrained(uint rcv_wnd) => (Kcp.MTU_DEF - Kcp.OVERHEAD - CHANNEL_HEADER_SIZE) * ((int)rcv_wnd - 1) - 1;

// kcp encodes 'frg' as 1 byte.
// max message size can only ever allow up to 255 fragments.
// kcp encodes 'frg' as 1 ushort.
// max message size can only ever allow up to 65535 fragments.
// WND_RCV gives 127 fragments.
// WND_RCV * 2 gives 255 fragments.
// so we can limit max message size by limiting rcv_wnd parameter.
Expand Down
22 changes: 11 additions & 11 deletions kcp2k/Assets/kcp2k/kcp/Kcp.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class Kcp
public const int MTU_DEF = 1200; // default MTU (reduced to 1200 to fit all cases: https://en.wikipedia.org/wiki/Maximum_transmission_unit ; steam uses 1200 too!)
public const int ACK_FAST = 3;
public const int INTERVAL = 100;
public const int OVERHEAD = 24;
public const int FRG_MAX = byte.MaxValue; // kcp encodes 'frg' as byte. so we can only ever send up to 255 fragments.
public const int OVERHEAD = 25; // original kcp uses 24 byte. we add 1 more byte for frg ushort max
miwarnec marked this conversation as resolved.
Show resolved Hide resolved
public const int FRG_MAX = ushort.MaxValue; // kcp encodes 'frg' as ushort. so we can only ever send up to 65535 fragments.
public const int DEADLINK = 20;
public const int THRESH_INIT = 2;
public const int THRESH_MIN = 2;
Expand Down Expand Up @@ -263,9 +263,9 @@ public int Send(byte[] buffer, int offset, int len)
if (len <= mss) count = 1;
else count = (int)((len + mss - 1) / mss);

// IMPORTANT kcp encodes 'frg' as 1 byte.
// so we can only support up to 255 fragments.
// (which limits max message size to around 288 KB)
// IMPORTANT kcp encodes 'frg' as 1 ushort.
// so we can only support up to 65535 fragments.
// (which limits max message size to around 70,000 KB)
// this is really nasty to debug. let's make this 100% obvious.
if (count > FRG_MAX)
throw new Exception($"Send len={len} requires {count} fragments, but kcp can only handle up to {FRG_MAX} fragments.");
Expand All @@ -290,7 +290,7 @@ public int Send(byte[] buffer, int offset, int len)
seg.data.Write(buffer, offset, size);
}
// seg.len = size: WriteBytes sets segment.Position!
seg.frg = (byte)(count - i - 1);
seg.frg = (ushort)(count - i - 1);
snd_queue.Enqueue(seg);
offset += size;
len -= size;
Expand Down Expand Up @@ -511,7 +511,7 @@ public int Input(byte[] data, int offset, int size)
uint conv_ = 0;
ushort wnd = 0;
byte cmd = 0;
byte frg = 0;
ushort frg = 0;

// enough data left to decode segment (aka OVERHEAD bytes)?
if (size < OVERHEAD) break;
Expand All @@ -521,10 +521,10 @@ public int Input(byte[] data, int offset, int size)
if (conv_ != conv) return -1;

offset += Utils.Decode8u(data, offset, ref cmd);
// IMPORTANT kcp encodes 'frg' as 1 byte.
// so we can only support up to 255 fragments.
// (which limits max message size to around 288 KB)
offset += Utils.Decode8u(data, offset, ref frg);
// IMPORTANT kcp encodes 'frg' as 1 ushort.
// so we can only support up to 65355 fragments.
// (which limits max message size to around 70,000 KB)
miwarnec marked this conversation as resolved.
Show resolved Hide resolved
offset += Utils.Decode16U(data, offset, ref frg);
offset += Utils.Decode16U(data, offset, ref wnd);
offset += Utils.Decode32U(data, offset, ref ts);
offset += Utils.Decode32U(data, offset, ref sn);
Expand Down
10 changes: 5 additions & 5 deletions kcp2k/Assets/kcp2k/kcp/Segment.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal class Segment
{
internal uint conv; // conversation
internal uint cmd; // command, e.g. Kcp.CMD_ACK etc.
internal uint frg; // fragment (sent as 1 byte)
internal uint frg; // fragment (sent as 1 ushort)
internal uint wnd; // window size that the receive can currently receive
internal uint ts; // timestamp
internal uint sn; // serial number
Expand All @@ -30,10 +30,10 @@ internal int Encode(byte[] ptr, int offset)
int offset_ = offset;
offset += Utils.Encode32U(ptr, offset, conv);
offset += Utils.Encode8u(ptr, offset, (byte)cmd);
// IMPORTANT kcp encodes 'frg' as 1 byte.
// so we can only support up to 255 fragments.
// (which limits max message size to around 288 KB)
offset += Utils.Encode8u(ptr, offset, (byte)frg);
// IMPORTANT kcp encodes 'frg' as 1 ushort.
// so we can only support up to 65355 fragments.
// (which limits max message size to around 70,000 KB)
miwarnec marked this conversation as resolved.
Show resolved Hide resolved
offset += Utils.Encode16U(ptr, offset, (ushort)frg);
offset += Utils.Encode16U(ptr, offset, (ushort)wnd);
offset += Utils.Encode32U(ptr, offset, ts);
offset += Utils.Encode32U(ptr, offset, sn);
Expand Down