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