Протокол TCP/IP для передачи и приема потоков


Это моя первая попытка на протокол TCP/IP и, честно говоря, я только начинаю на C#, поэтому любые замечания по конструкции, методу и т. д., Более чем приветствуется.

В принципе я хотел создать какой-нить слушал и однажды отправив поток, который может обрабатывать слушать/отправки контрольных сообщений, а также другие сообщения.

После получения сообщения, она будет изменять некоторые значения в основную программу исполнения.

public virtual void StartReceivingThread()
{
    Thread thrReceive = new Thread(Receive);
    try
    {
        if (!bIsActive && Connect())
        {
            //NOTE: exception thrown by a thread can only be captured by that thread itself
            //start a listen thread
            //wait until heartbeat message is accepted

            thrReceive.Name = "thr" + serviceType.Name;
            thrReceive.Start();
            bIsActive = true;

            //wait to get the heartbeat message
            for (int i = 0; i < maxRetry; i++)
            {
                Thread.Sleep(maxTimeOutValue);
                if (bIsReceivingHeartbeat)
                    break;
            }
            //if nothing happens close the connection and try again
            if (!bIsReceivingHeartbeat)
            {
                bIsActive = false;
                CleanUp();
                logger.Info("Closing  receiver thread - " + thrReceive.Name);
            }
            else
            {
                logger.Info("Starting  receiver thread - " + thrReceive.Name);
            }
        }


    }
    catch(Exception ex)
    {
        logger.Error(ex);
    }
    //finally
    //{
    //    logger.Info("Exiting  receiver thread - " + thrReceive.Name);
    //}
}

public void CleanUp()
{
    if (client != null)
    {
        client.Close();
    }
}

public virtual void Receive()
{
    string eventMessage = string.Empty;
    int bytesRcvd = 0;
    int totalBytesRcvd = 0;
    byte[] byteBuffer = new byte[maxBufferSize];
    NetworkStream listenStream;
    try
    {
        if (client.Connected)
        {
            listenStream = client.GetStream();    
        }
        else
        {
            return;
        }

        while (true)
        {                
            //message that is slot in from the object will get sent here.
            if (!string.IsNullOrEmpty(MessageToSend))
            {
                Send(MessageToSend);
                MessageToSend = string.Empty;
            }

            // must convert it back and look for the delimiter, cannot wait for the three heartbeat to pass
            string leftoverMsg = string.Empty;

            bytesRcvd = listenStream.Read(byteBuffer, totalBytesRcvd, maxBufferSize - totalBytesRcvd);
            totalBytesRcvd += bytesRcvd;

            //if more than heart beat size, can process to see if it's a heartbeat and proceed to send
            if (totalBytesRcvd > msgHeartbeatSize)
            {
                eventMessage = Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd);
                ProcessMessage(eventMessage, ref leftoverMsg, ref totalBytesRcvd, ref byteBuffer);
            }
        }
    }
    catch (ThreadAbortException thEx)
    {
        //do nothing as main thread has aborted and waiting to close
        logger.Info(Thread.CurrentThread.Name + " is stopped. ");
    }
    catch (Exception exce)
    {
        bIsActive = false;
        logger.Error(exce);
        CleanUp();
    }
    finally
    {
        logger.Info(String.Format("Thread {0} Exiting. ", Thread.CurrentThread.Name));
    }
}

public void Send(string msg)
{
    StringBuilder sb = new StringBuilder();
    sb.Append(Char.STX);
    sb.Append(msg);
    sb.Append(Char.ETX);

    try
    {
        string message = sb.ToString();
        byte[] byteBuffer = Encoding.ASCII.GetBytes(message);

        //use a different stream to prevent blocking?
        NetworkStream sendNetStream = client.GetStream();
        sendNetStream.Write(byteBuffer, 0, byteBuffer.Length);
        sendNetStream.Flush(); //clear buffer straight without waiting for the write buffer to fill up.

        //simplify the heart beat message for logging
        if (simpleHeartbeatMsg.ToLower().Contains("on") 
            && message.Contains("fnxheartbeatack"))
        {
            message = "heartbeat message.";
        }
        logger.Info("Sending to   - xml: " + Char.GetNonFormattedString(message));

    }
    catch (Exception ex)
    {
        bIsActive = false;
        CleanUp();
        sb = null;
        throw ex;
    }
}


3904
2
задан 3 ноября 2011 в 07:11 Источник Поделиться
Комментарии
1 ответ

Приходят несколько вещей в виду при чтении этой...


  • Установить приоритет потока. Помните, что расплодили темы не соблюдать приоритет процесса. Поэтому вам нужно решить, какого уровня это должно быть по отношению к другим приоритетам

  • Это будет поток изображения, это действительно то, что вы хотите здесь. Другими словами, когда хост-процесс идет, надо эту ветку повесить процесс, пока ваш аборт? Рассмотрим вариант фона

  • С помощью спин-шаблон с сна не может быть лучшим способом пойти. Рассмотрите возможность использования монитора.Пульс/шаблон Подождите, вы даже можете установить тайм-аут ожидания в случае необходимости.

  • Если регистратор есть, такой как log4net, убедитесь, что используете если (логгер.IsInfoEnabled()) рисунок, который рекомендован владельцем проекта. Это компенсирует какие-то внутренние расходы.

  • В очистка() метод не видна в вашем посте, но это называется внутри поймать блок. Убедитесь, что это не исключение тоже

  • Почти весь код находится внутри попробовать-catch блок. При этом никто из них не будет иметь право на оптимизацию JIT. В зависимости от ваших потребностей в производительности, это может быть проблемой. Переместить внутренности попробуйте раздел на отдельные методы

  • Учитывая ваше использование класса StringBuilder будет стоить 2 или 3 раза больше, потом просто делал х+г или строку.функция concat(Х, Y). Напишите тест производительности вокруг этих и ваш увидите, что я имею в виду

  • Используя ToUpper() против нижестоящим() является более эффективным

  • Ваш не закрывать и не удалять вашем объекте networkstream

Надеюсь, что это помогает

3
ответ дан 16 декабря 2011 в 08:12 Источник Поделиться