/// <exception cref="System.IO.IOException"></exception>
        internal virtual void Send(NameServicePacket request,
                                   NameServicePacket response,
                                   int timeout)
        {
            //Log.Out("NameSerciceClient.Send - Start");

            int nid = 0;
            int max = NbtAddress.Nbns.Length;

            if (max == 0)
            {
                max = 1;
            }

            lock (response)
            {
                this._isActive = true;

                while (max-- > 0)
                {
                    try
                    {
                        lock (_lock)
                        {
                            request.NameTrnId = GetNextNameTrnId();
                            nid = request.NameTrnId;

                            response.Received = false;
                            _responseTable.Put(nid, response);

                            //Log.Out($"NameSerciceClient.Send - timeout = {timeout}");
                            EnsureOpen(timeout + 1000);

                            int    requestLenght = request.WriteWireFormat(_sndBuf, 0);
                            byte[] msg           = new byte[requestLenght];
                            Array.Copy(_sndBuf, msg, requestLenght);

                            _socketSender.SetSocketOption(SocketOptionLevel.Socket,
                                                          SocketOptionName.Broadcast,
                                                          request.IsBroadcast
                                                            ? 1
                                                            : 0);

                            _socketSender.SendTo(msg, new IPEndPoint(request.Addr, _lport));
                            //Log.Out("NameSerciceClient.Send - Sended");

                            if (_log.Level > 3)
                            {
                                _log.WriteLine(request);
                                Hexdump.ToHexdump(_log, _sndBuf, 0, requestLenght);
                            }
                        }

                        if (_waitResponse)
                        {
                            long start      = Runtime.CurrentTimeMillis();
                            var  isRecieved = false;
                            var  startTime  = DateTime.Now;
                            while (timeout > 0)
                            {
                                Runtime.Wait(response, timeout);
                                if (response.Received && request.QuestionType == response.RecordType)
                                {
                                    //return;
                                    isRecieved = true;
                                    break;
                                }
                                response.Received = false;
                                timeout          -= (int)(Runtime.CurrentTimeMillis() - start);

                                //if (timeout <= 0)
                                //{
                                //    Log.Out($"NameSerciceClient.Send Timeout! - {(DateTime.Now - startTime).TotalMilliseconds} msec");
                                //}
                            }

                            if (isRecieved)
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception ie)
                    {
                        if (_waitResponse)
                        {
                            _responseTable.Remove(nid);
                        }

                        //Log.Out("NameSerciceClient.Send - IOException");

                        throw new IOException(ie.Message);
                    }
                    finally
                    {
                        if (_waitResponse)
                        {
                            _responseTable.Remove(nid);
                        }
                    }

                    if (_waitResponse)
                    {
                        lock (_lock)
                        {
                            if (NbtAddress.IsWins(request.Addr) == false)
                            {
                                break;
                            }
                            if (request.Addr == NbtAddress.GetWinsAddress())
                            {
                                NbtAddress.SwitchWins();
                            }
                            request.Addr = NbtAddress.GetWinsAddress();
                        }
                    }
                }

                this._isActive = false;
                //Log.Out("NameSerciceClient.Send - Normaly Ended.");
            }
        }