예제 #1
0
        private void Dns_Resolve(IAsyncResult ar)
        {
            Random        rnd = new Random();
            IPHostEntry   hostent;
            ConnQueueItem nextconn = (ConnQueueItem)(ar.AsyncState);

            while (!ar.IsCompleted)
            {
                ar.AsyncWaitHandle.WaitOne(10, false);
            }
            try
            {
                hostent = Dns.EndGetHostEntry(ar);
            }
            catch (Exception e2)
            {
                // DNS Failed.
                BufferedSocket sck = new BufferedSocket(null);
                sck.sckError = e2;
                nextconn.cb(sck);
                return;
            }
            nextconn.address = hostent.AddressList[rnd.Next(hostent.AddressList.Length)].ToString();
            lock (this)
            {
                connectionqueue.Enqueue(nextconn);
            }
        }
예제 #2
0
 private void SocketThread()
 {
     try
     {
         // Loop "forever".
         while (true)
         {
             // Even a tiny sleep like this goes a long way to keeping us from using 100% CPU.
             try { Thread.Sleep(10); }
             catch (ThreadInterruptedException) {}
             lock (this)
             {
                 if ((sockets.Count + connectionqueue.Count) < 1)
                 {
                     continue;
                 }
                 // Process EXACTLY ONE connection attempt each time through. If we must DNS,
                 // then do so and then put the attempt back on the end.
                 if (connectionqueue.Count > 0)
                 {
                     ConnQueueItem nextconn = connectionqueue.Dequeue();
                     IPAddress     ip;
                     try
                     {
                         ip = IPAddress.Parse(nextconn.address);
                         // We have IP - CONNECT!
                         BufferedSocket sck = new BufferedSocket(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp));
                         try
                         {
                             sck.sck.Connect(new IPEndPoint(ip, nextconn.port));
                             // CONNECTED! Notify the callback.
                             nextconn.cb(sck);
                             sockets.Add(sck);
                         }
                         catch (Exception e)
                         {
                             // Connect Failed :( Notify the callback. The callback doesn't need to try to remove - in fact it MUST NOT! I don't know what a double-lock might entail ;) .
                             sck.sck      = null;
                             sck.sckError = e;
                             nextconn.cb(sck);
                         }
                     }
                     catch (Exception)
                     {
                         // We must DNS.
                         try
                         {
                             Dns.BeginGetHostEntry(nextconn.address, new AsyncCallback(Dns_Resolve), nextconn);
                         }
                         catch (Exception e2)
                         {
                             // DNS Failed.
                             BufferedSocket sck = new BufferedSocket(null);
                             sck.sckError = e2;
                             nextconn.cb(sck);
                         }
                     }
                 }
                 // Now process Socket buffers.
                 foreach (BufferedSocket sck in sockets)
                 {
                     lock (sck)
                     {
                         // We shouldn't send more than about 1KB at a time, to avoid blocking
                         // in Send().
                         // If we're pending disconnect...
                         if (sck.sck == null)
                         {
                             continue;
                         }
                         if (sck.PendingDisconnect)
                         {
                             if (sck.sck.Poll(0, SelectMode.SelectWrite) && sck.sendbuffer.Length > 0)
                             {
                                 sck.sck.Send(Encoding.ASCII.GetBytes(sck.sendbuffer));
                             }
                             sck.sendbuffer = "";
                             sck.sck.Shutdown(SocketShutdown.Both);
                             sck.sck.Close();
                             sck.sck = null;
                             continue;
                         }
                         if (sck.sendbuffer.Length > 0)
                         {
                             byte[] data;
                             if (sck.sendbuffer.Length > 1024)
                             {
                                 data           = Encoding.ASCII.GetBytes(sck.sendbuffer.Substring(0, 1024));
                                 sck.sendbuffer = sck.sendbuffer.Substring(1024);
                             }
                             else
                             {
                                 data           = Encoding.ASCII.GetBytes(sck.sendbuffer);
                                 sck.sendbuffer = "";
                             }
                             sck.sck.Send(data);
                         }
                         if (sck.sck.Poll(0, SelectMode.SelectRead) && sck.sck.Available <= 0)
                         {
                             // Remote endpoint disconnected.
                             sck.sendbuffer = "";
                             if (sck.sck.Poll(0, SelectMode.SelectWrite))
                             {
                                 sck.sck.Shutdown(SocketShutdown.Send);
                             }
                             sck.sck.Close();
                             sck.sck = null;
                         }
                         else if (sck.sck.Available > 0)
                         {
                             byte[] data = new byte[sck.sck.Available];
                             sck.sck.Receive(data);
                             sck.recvbuffer += Encoding.ASCII.GetString(data);
                         }
                         // In case someone had called Monitor.Wait() on this sck, pulse it.
                         Monitor.PulseAll(sck);
                     }
                 }
             }
         }
     }
     catch (ThreadAbortException)
     {
     }
 }