Skip to content

Commit 25d2036

Browse files
committed
Added support for receiving responses from the broadcasted messages
1 parent d921047 commit 25d2036

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

kcp2k/Assets/kcp2k/highlevel/KcpClient.cs

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

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

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

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

kcp2k/Assets/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/Assets/kcp2k/highlevel/KcpServer.cs

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

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

67-
static Socket CreateServerSocket(bool DualMode, ushort port)
67+
static Socket CreateServerSocket(bool DualMode, ushort port, bool enableBroadcast)
6868
{
6969
if (DualMode)
7070
{
@@ -82,13 +82,15 @@ static Socket CreateServerSocket(bool DualMode, ushort port)
8282
{
8383
Log.Warning($"Failed to set Dual Mode, continuing with IPv6 without Dual Mode. Error: {e}");
8484
}
85+
socket.EnableBroadcast = enableBroadcast;
8586
socket.Bind(new IPEndPoint(IPAddress.IPv6Any, port));
8687
return socket;
8788
}
8889
else
8990
{
9091
// IPv4 socket @ "0.0.0.0" : port
9192
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
93+
socket.EnableBroadcast = enableBroadcast;
9294
socket.Bind(new IPEndPoint(IPAddress.Any, port));
9395
return socket;
9496
}
@@ -104,7 +106,7 @@ public virtual void Start(ushort port)
104106
}
105107

106108
// listen
107-
socket = CreateServerSocket(config.DualMode, port);
109+
socket = CreateServerSocket(config.DualMode, port, config.EnableBroadcast);
108110

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

0 commit comments

Comments
 (0)