Skip to content

Commit 07fe1b5

Browse files
committed
Added support for receiving responses from the broadcasted messages
1 parent e46df2f commit 07fe1b5

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

kcp2k/kcp2k/highlevel/KcpClient.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,22 @@ void OnDisconnectedWrap()
111111
// even a 1ms block per connection would stop us from scaling.
112112
socket.Blocking = false;
113113

114+
// set flag to be able to send/recv broadcast messages if needed
115+
socket.EnableBroadcast = config.EnableBroadcast;
116+
114117
// configure buffer sizes
115118
Common.ConfigureSocketBuffers(socket, config.RecvBufferSize, config.SendBufferSize);
116119

117120
// bind to endpoint so we can use send/recv instead of sendto/recvfrom.
118-
socket.Connect(remoteEndPoint);
121+
// But we don't do that if we want to be able to receive answers to
122+
// broadcast requests, we must use socket.SendTo instead of socket.Connect.
123+
// Otherwise broadcast address will be bound to the socket and it will be
124+
// trying to receive data from it instead of the real address of
125+
// the client and nothing will be received.
126+
if (!config.EnableBroadcast)
127+
{
128+
socket.Connect(remoteEndPoint);
129+
}
119130

120131
// client should send handshake to server as very first message
121132
peer.SendHandshake();
@@ -155,7 +166,18 @@ protected virtual void RawSend(ArraySegment<byte> data)
155166
{
156167
try
157168
{
158-
socket.SendNonBlocking(data);
169+
// if broadcast enabled, we use connectionless mode and must send
170+
// data using the SendTo method. Note that using this method causes
171+
// allocations (remoteEndPoint is re-serialized each time). Thus it
172+
// is recommended to use broadcast-enabled client ONLY for discovery.
173+
if (config.EnableBroadcast)
174+
{
175+
socket.SendToNonBlocking(data, remoteEndPoint);
176+
}
177+
else
178+
{
179+
socket.SendNonBlocking(data);
180+
}
159181
}
160182
catch (SocketException e)
161183
{

kcp2k/kcp2k/highlevel/KcpConfig.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ public class KcpConfig
6363
// maximum retransmission attempts until dead_link
6464
public uint MaxRetransmits;
6565

66+
// Whether to enable broadcasting. If true, the client will be able
67+
// to broadcast messages and the server will be able to receive them
68+
// and reply.
69+
public bool EnableBroadcast;
70+
6671
// constructor /////////////////////////////////////////////////////////
6772
// constructor with defaults for convenience.
6873
// makes it easy to define "new KcpConfig(DualMode=false)" etc.
@@ -78,7 +83,8 @@ public KcpConfig(
7883
uint SendWindowSize = Kcp.WND_SND,
7984
uint ReceiveWindowSize = Kcp.WND_RCV,
8085
int Timeout = KcpPeer.DEFAULT_TIMEOUT,
81-
uint MaxRetransmits = Kcp.DEADLINK)
86+
uint MaxRetransmits = Kcp.DEADLINK,
87+
bool EnableBroadcast = false)
8288
{
8389
this.DualMode = DualMode;
8490
this.RecvBufferSize = RecvBufferSize;
@@ -92,6 +98,7 @@ public KcpConfig(
9298
this.ReceiveWindowSize = ReceiveWindowSize;
9399
this.Timeout = Timeout;
94100
this.MaxRetransmits = MaxRetransmits;
101+
this.EnableBroadcast = EnableBroadcast;
95102
}
96103
}
97104
}

kcp2k/kcp2k/highlevel/KcpServer.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public KcpServer(Action<int> OnConnected,
6363

6464
public virtual bool IsActive() => socket != null;
6565

66-
static Socket CreateServerSocket(bool DualMode, ushort port)
66+
static Socket CreateServerSocket(bool DualMode, ushort port, bool enableBroadcast)
6767
{
6868
if (DualMode)
6969
{
@@ -81,13 +81,15 @@ static Socket CreateServerSocket(bool DualMode, ushort port)
8181
{
8282
Log.Warning($"Failed to set Dual Mode, continuing with IPv6 without Dual Mode. Error: {e}");
8383
}
84+
socket.EnableBroadcast = enableBroadcast;
8485
socket.Bind(new IPEndPoint(IPAddress.IPv6Any, port));
8586
return socket;
8687
}
8788
else
8889
{
8990
// IPv4 socket @ "0.0.0.0" : port
9091
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
92+
socket.EnableBroadcast = enableBroadcast;
9193
socket.Bind(new IPEndPoint(IPAddress.Any, port));
9294
return socket;
9395
}
@@ -103,7 +105,7 @@ public virtual void Start(ushort port)
103105
}
104106

105107
// listen
106-
socket = CreateServerSocket(config.DualMode, port);
108+
socket = CreateServerSocket(config.DualMode, port, config.EnableBroadcast);
107109

108110
// recv & send are called from main thread.
109111
// need to ensure this never blocks.

0 commit comments

Comments
 (0)