Skip to content

Commit ab82fc6

Browse files
author
mischa
committed
message consts moved back into KcpPeer to not break the API
1 parent 6986e2e commit ab82fc6

3 files changed

Lines changed: 61 additions & 61 deletions

File tree

kcp2k/kcp2k.Tests/ClientServerTests.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ public void ClientToServerReliableMaxSizedMessage()
316316
server.Start(Port);
317317
ConnectClientBlocking();
318318

319-
byte[] message = new byte[Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)];
319+
byte[] message = new byte[KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)];
320320
for (int i = 0; i < message.Length; ++i)
321321
message[i] = (byte)(i & 0xFF);
322322
Log.Info($"Sending {message.Length} bytes = {message.Length / 1024} KB message");
@@ -334,7 +334,7 @@ public void ClientToServerUnreliableMaxSizedMessage()
334334
server.Start(Port);
335335
ConnectClientBlocking();
336336

337-
byte[] message = new byte[Common.UnreliableMaxMessageSize(config.Mtu)];
337+
byte[] message = new byte[KcpPeer.UnreliableMaxMessageSize(config.Mtu)];
338338
for (int i = 0; i < message.Length; ++i)
339339
message[i] = (byte)(i & 0xFF);
340340
Log.Info($"Sending {message.Length} bytes = {message.Length / 1024} KB message");
@@ -374,10 +374,10 @@ public void ClientToServerTooLargeReliableMessage()
374374
server.Start(Port);
375375
ConnectClientBlocking();
376376

377-
byte[] message = new byte[Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize) + 1];
377+
byte[] message = new byte[KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize) + 1];
378378

379379
#if UNITY_2018_3_OR_NEWER
380-
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Warning, new Regex($".*Failed to send reliable message of size {message.Length} because it's larger than ReliableMaxMessageSize={Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)}"));
380+
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Warning, new Regex($".*Failed to send reliable message of size {message.Length} because it's larger than ReliableMaxMessageSize={KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)}"));
381381
#endif
382382
SendClientToServerBlocking(new ArraySegment<byte>(message), KcpChannel.Reliable);
383383
Assert.That(serverReceived.Count, Is.EqualTo(0));
@@ -389,9 +389,9 @@ public void ClientToServerTooLargeUnreliableMessage()
389389
server.Start(Port);
390390
ConnectClientBlocking();
391391

392-
byte[] message = new byte[Common.UnreliableMaxMessageSize(config.Mtu) + 1];
392+
byte[] message = new byte[KcpPeer.UnreliableMaxMessageSize(config.Mtu) + 1];
393393
#if UNITY_2018_3_OR_NEWER
394-
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Error, new Regex($".*Failed to send unreliable message of size {message.Length} because it's larger than UnreliableMaxMessageSize={Common.UnreliableMaxMessageSize(config.Mtu)}"));
394+
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Error, new Regex($".*Failed to send unreliable message of size {message.Length} because it's larger than UnreliableMaxMessageSize={KcpPeer.UnreliableMaxMessageSize(config.Mtu)}"));
395395
#endif
396396
SendClientToServerBlocking(new ArraySegment<byte>(message), KcpChannel.Unreliable);
397397
Assert.That(serverReceived.Count, Is.EqualTo(0));
@@ -455,7 +455,7 @@ public void ClientToServerMultipleReliableMaxSizedMessagesAtOnce()
455455
for (int i = 0; i < 10; ++i)
456456
{
457457
// create message, fill with unique data (j+i & 0xff)
458-
byte[] message = new byte[Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)];
458+
byte[] message = new byte[KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)];
459459
for (int j = 0; j < message.Length; ++j)
460460
message[j] = (byte)((j + i) & 0xFF);
461461
messages.Add(message);
@@ -492,7 +492,7 @@ public void ClientToServerMultipleUnreliableMaxSizedMessagesAtOnce()
492492
for (int i = 0; i < 10; ++i)
493493
{
494494
// create message, fill with unique data (j+i & 0xff)
495-
byte[] message = new byte[Common.UnreliableMaxMessageSize(config.Mtu)];
495+
byte[] message = new byte[KcpPeer.UnreliableMaxMessageSize(config.Mtu)];
496496
for (int j = 0; j < message.Length; ++j)
497497
message[j] = (byte)((j + i) & 0xFF);
498498
messages.Add(message);
@@ -643,7 +643,7 @@ public void ServerToClientReliableMaxSizedMessage()
643643
ConnectClientBlocking();
644644
int connectionId = ServerFirstConnectionId();
645645

646-
byte[] message = new byte[Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)];
646+
byte[] message = new byte[KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)];
647647
for (int i = 0; i < message.Length; ++i)
648648
message[i] = (byte)(i & 0xFF);
649649

@@ -662,7 +662,7 @@ public void ServerToClientUnreliableMaxSizedMessage()
662662
ConnectClientBlocking();
663663
int connectionId = ServerFirstConnectionId();
664664

665-
byte[] message = new byte[Common.UnreliableMaxMessageSize(config.Mtu)];
665+
byte[] message = new byte[KcpPeer.UnreliableMaxMessageSize(config.Mtu)];
666666
for (int i = 0; i < message.Length; ++i)
667667
message[i] = (byte)(i & 0xFF);
668668

@@ -704,9 +704,9 @@ public void ServerToClientTooLargeReliableMessage()
704704
ConnectClientBlocking();
705705
int connectionId = ServerFirstConnectionId();
706706

707-
byte[] message = new byte[Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize) + 1];
707+
byte[] message = new byte[KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize) + 1];
708708
#if UNITY_2018_3_OR_NEWER
709-
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Warning, new Regex($".*Failed to send reliable message of size {message.Length} because it's larger than ReliableMaxMessageSize={Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)}"));
709+
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Warning, new Regex($".*Failed to send reliable message of size {message.Length} because it's larger than ReliableMaxMessageSize={KcpPeer.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize)}"));
710710
#endif
711711
SendServerToClientBlocking(connectionId, new ArraySegment<byte>(message), KcpChannel.Reliable);
712712
Assert.That(clientReceived.Count, Is.EqualTo(0));
@@ -720,10 +720,10 @@ public void ServerToClientTooLargeUnreliableMessage()
720720
ConnectClientBlocking();
721721
int connectionId = ServerFirstConnectionId();
722722

723-
byte[] message = new byte[Common.UnreliableMaxMessageSize(config.Mtu) + 1];
723+
byte[] message = new byte[KcpPeer.UnreliableMaxMessageSize(config.Mtu) + 1];
724724

725725
#if UNITY_2018_3_OR_NEWER
726-
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Error, new Regex($".*Failed to send unreliable message of size {message.Length} because it's larger than UnreliableMaxMessageSize={Common.UnreliableMaxMessageSize(config.Mtu)}"));
726+
UnityEngine.TestTools.LogAssert.Expect(UnityEngine.LogType.Error, new Regex($".*Failed to send unreliable message of size {message.Length} because it's larger than UnreliableMaxMessageSize={KcpPeer.UnreliableMaxMessageSize(config.Mtu)}"));
727727
#endif
728728
SendServerToClientBlocking(connectionId, new ArraySegment<byte>(message), KcpChannel.Unreliable);
729729
Assert.That(clientReceived.Count, Is.EqualTo(0));

kcp2k/kcp2k/highlevel/Common.cs

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,6 @@ namespace kcp2k
77
{
88
public static class Common
99
{
10-
// we need to subtract the channel and cookie bytes from every
11-
// MaxMessageSize calculation.
12-
// we also need to tell kcp to use MTU-1 to leave space for the byte.
13-
public const int CHANNEL_HEADER_SIZE = 1;
14-
public const int COOKIE_HEADER_SIZE = 4;
15-
public const int METADATA_SIZE = CHANNEL_HEADER_SIZE + COOKIE_HEADER_SIZE;
16-
17-
// reliable channel (= kcp) MaxMessageSize so the outside knows largest
18-
// allowed message to send. the calculation in Send() is not obvious at
19-
// all, so let's provide the helper here.
20-
//
21-
// kcp does fragmentation, so max message is way larger than MTU.
22-
//
23-
// -> runtime MTU changes are disabled: mss is always MTU_DEF-OVERHEAD
24-
// -> Send() checks if fragment count < rcv_wnd, so we use rcv_wnd - 1.
25-
// NOTE that original kcp has a bug where WND_RCV default is used
26-
// instead of configured rcv_wnd, limiting max message size to 144 KB
27-
// https://github.com/skywind3000/kcp/pull/291
28-
// we fixed this in kcp2k.
29-
// -> we add 1 byte KcpHeader enum to each message, so -1
30-
//
31-
// IMPORTANT: max message is MTU * rcv_wnd, in other words it completely
32-
// fills the receive window! due to head of line blocking,
33-
// all other messages have to wait while a maxed size message
34-
// is being delivered.
35-
// => in other words, DO NOT use max size all the time like
36-
// for batching.
37-
// => sending UNRELIABLE max message size most of the time is
38-
// best for performance (use that one for batching!)
39-
static int ReliableMaxMessageSize_Unconstrained(int mtu, uint rcv_wnd) =>
40-
(mtu - Kcp.OVERHEAD - METADATA_SIZE) * ((int)rcv_wnd - 1) - 1;
41-
42-
// kcp encodes 'frg' as 1 byte.
43-
// max message size can only ever allow up to 255 fragments.
44-
// WND_RCV gives 127 fragments.
45-
// WND_RCV * 2 gives 255 fragments.
46-
// so we can limit max message size by limiting rcv_wnd parameter.
47-
public static int ReliableMaxMessageSize(int mtu, uint rcv_wnd) =>
48-
ReliableMaxMessageSize_Unconstrained(mtu, Math.Min(rcv_wnd, Kcp.FRG_MAX));
49-
50-
// unreliable max message size is simply MTU - channel header size
51-
public static int UnreliableMaxMessageSize(int mtu) =>
52-
mtu - METADATA_SIZE;
53-
5410
// helper function to resolve host to IPAddress
5511
public static bool ResolveHostname(string hostname, out IPAddress[] addresses)
5612
{

kcp2k/kcp2k/highlevel/KcpPeer.cs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,50 @@ public abstract class KcpPeer
7878
public int SendBufferCount => kcp.snd_buf.Count;
7979
public int ReceiveBufferCount => kcp.rcv_buf.Count;
8080

81+
// we need to subtract the channel and cookie bytes from every
82+
// MaxMessageSize calculation.
83+
// we also need to tell kcp to use MTU-1 to leave space for the byte.
84+
public const int CHANNEL_HEADER_SIZE = 1;
85+
public const int COOKIE_HEADER_SIZE = 4;
86+
public const int METADATA_SIZE = CHANNEL_HEADER_SIZE + COOKIE_HEADER_SIZE;
87+
88+
// reliable channel (= kcp) MaxMessageSize so the outside knows largest
89+
// allowed message to send. the calculation in Send() is not obvious at
90+
// all, so let's provide the helper here.
91+
//
92+
// kcp does fragmentation, so max message is way larger than MTU.
93+
//
94+
// -> runtime MTU changes are disabled: mss is always MTU_DEF-OVERHEAD
95+
// -> Send() checks if fragment count < rcv_wnd, so we use rcv_wnd - 1.
96+
// NOTE that original kcp has a bug where WND_RCV default is used
97+
// instead of configured rcv_wnd, limiting max message size to 144 KB
98+
// https://github.com/skywind3000/kcp/pull/291
99+
// we fixed this in kcp2k.
100+
// -> we add 1 byte KcpHeader enum to each message, so -1
101+
//
102+
// IMPORTANT: max message is MTU * rcv_wnd, in other words it completely
103+
// fills the receive window! due to head of line blocking,
104+
// all other messages have to wait while a maxed size message
105+
// is being delivered.
106+
// => in other words, DO NOT use max size all the time like
107+
// for batching.
108+
// => sending UNRELIABLE max message size most of the time is
109+
// best for performance (use that one for batching!)
110+
static int ReliableMaxMessageSize_Unconstrained(int mtu, uint rcv_wnd) =>
111+
(mtu - Kcp.OVERHEAD - METADATA_SIZE) * ((int)rcv_wnd - 1) - 1;
112+
113+
// kcp encodes 'frg' as 1 byte.
114+
// max message size can only ever allow up to 255 fragments.
115+
// WND_RCV gives 127 fragments.
116+
// WND_RCV * 2 gives 255 fragments.
117+
// so we can limit max message size by limiting rcv_wnd parameter.
118+
public static int ReliableMaxMessageSize(int mtu, uint rcv_wnd) =>
119+
ReliableMaxMessageSize_Unconstrained(mtu, Math.Min(rcv_wnd, Kcp.FRG_MAX));
120+
121+
// unreliable max message size is simply MTU - channel header size
122+
public static int UnreliableMaxMessageSize(int mtu) =>
123+
mtu - METADATA_SIZE;
124+
81125
// maximum send rate per second can be calculated from kcp parameters
82126
// source: https://translate.google.com/translate?sl=auto&tl=en&u=https://wetest.qq.com/lab/view/391.html
83127
//
@@ -115,8 +159,8 @@ protected KcpPeer(KcpConfig config, uint cookie)
115159
rawSendBuffer = new byte[config.Mtu];
116160

117161
// calculate max message sizes once
118-
unreliableMax = Common.UnreliableMaxMessageSize(config.Mtu);
119-
reliableMax = Common.ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize);
162+
unreliableMax = UnreliableMaxMessageSize(config.Mtu);
163+
reliableMax = ReliableMaxMessageSize(config.Mtu, config.ReceiveWindowSize);
120164

121165
// create message buffers AFTER window size is set
122166
// see comments on buffer definition for the "+1" part
@@ -146,7 +190,7 @@ protected void Reset(KcpConfig config)
146190
// message. so while Kcp.MTU_DEF is perfect, we actually need to
147191
// tell kcp to use MTU-1 so we can still put the header into the
148192
// message afterwards.
149-
kcp.SetMtu((uint)config.Mtu - Common.METADATA_SIZE);
193+
kcp.SetMtu((uint)config.Mtu - METADATA_SIZE);
150194

151195
// set maximum retransmits (aka dead_link)
152196
kcp.dead_link = config.MaxRetransmits;

0 commit comments

Comments
 (0)