@@ -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 {
0 commit comments