Исходные коды программ и игр

Программирование - работа и хобби

Протокол TCP, отправка текстовых сообщений по сети

Язык программирования C#

Сетевые приложения TCP

исходник сетевой программы протокол TCPИсходные коды на C# клиентского и серверного приложения работающие по протоколуTCP. TCP - отличается от протокола UDP наличием постоянного соединения и гарантирующем доставку отправлений в неизменном виде. Приложения построены на высокоуровневых классах TcpListener, TcpClient. Данные классы инкапсулируют в себе более низкоуровневый Socket, предоставляя готовые настройки для прослушивающего сокета - TcpListener, и сокета создающего клиентское подключение - TcpClient.

Сетевой протокол TCP

TCP аббревиатура Transmission Control Protocol, протокол (правила) управления передачей. Протокол TCP разработан для надежной передачи данных через сеть компьютеров. TCP (протокол управления передачей) для своей функциональности требует наличие постоянного соединения между сетевыми процессами. Разбивая отсылаемое сообщение на части, называемые пакетами, TCP помечает их таким образом, что независимо от очереди доставки этих пакетов сообщение будет собрано точно, так как оно и было изначально. Причем при потере части данных механизм протокола управления передачей запросит потерянные пакеты повторно. При этом он ещё и проверяет целостность каждого пакета. История TCP официально начинается с 1974 года, с тех пор написано много технических статей тщательным образом анализирующих механизм функционирования TCP.

Приложение сервер

Серверное приложение способно принимать запросы на подключение от нескольких клиентов. Для подключения использует блокирующий метод класса TcpListener.AcceptTcpClient возвращающий объект класса TcpClient. Чтобы не задерживать работу интерфейса программы данный метод запускается в отдельном потоке, останавливающийся после подключения установленного максимального количества клиентов. При успешном подключении запускается поток извлечения сообщений для каждого клиента отдельно. Метод ответственный за прием сообщений ReceiveRun(object num) в качестве параметра получает индекс подключившегося клиента. Сервер после получения сообщения ретранслирует его всем подключившимся клиентам. Потоки извлечения сообщений работают до завершения работы приложения или до остановки сервера.

Извлечение сообщения от клиента и ретрансляция полученного сообщения другим клиентам


void ReceiveRun(object num)
{
    while (true)
    {
        try
        {
            string s = null;
            NetworkStream ns = clients[(int)num].GetStream();

            // Раскомментировав строчку ниже,
            // тем самым уменьшив размер приемного буфера, можно убедиться,
            // что прием данных будет все равно осуществляться полностью.
            // clients[(int)num].ReceiveBufferSize = 2;
            while (ns.DataAvailable == true)
            {
                // Определить точный размер буфера приема
                // позволяет свойство класса TcpClient Available
                byte[] buffer = new byte[clients[(int)num].Available];

                ns.Read(buffer, 0, buffer.Length);
                // Волшебная функция превращающая поток байтов
                // в текстовые символы.
                s += Encoding.Default.GetString(buffer);
            }

            if (s != null)
            {
                // Данный метод, хотя и вызывается в отдельном потоке (не в главном),
                // но находит родительский поток и выполняет
                // делегат указанный в качестве параметра
                // в главном потоке, безопасно обновляя интерфейс формы.
                Invoke(new UpdateReceiveDisplayDelegate(UpdateReceiveDisplay),
						new object[] { (int)num, s });

                // Принятое сообщение от клиента перенаправляем всем клиентам
                // кроме текущего.
                s = "№" + ((int)num).ToString() + ": " + s;
                SendToClients(s, (int)num);
                s = String.Empty;
            }

            // Пока доступных данных нет притормозим деятельность потока.
            // Вынужденная строчка для экономия ресурсов процессора.
            // 100 мс достаточное время остановки потока на каждой итерации цикла
            // чтобы разгрузить процессор. Для корректного извлечения сообщений это
            // неизящный способ регламентирования работы потока.
            Thread.Sleep(100);
        }
        catch
        {
            // Перехватим возможные исключения
            ErrorSound();
        }


        if (_stopNetwork == true) break;

    }
}

Клиент-приложение

Исходник клиентского приложения более простой. Функции его заключаются в подключении к серверу и приему-отправки сообщений. Используются только блокирующие методы, причем метод извлечения сообщений ReceiveRun() работает в вспомогательном потоке, а метод отправки сообщений SendMessage() в главном потоке, поскольку сообщения отправляются почти мгновенно и практически не блокируют интерфейс.

Безопасный доступ к интерфейсу формы осуществляем сформированным методом ShowReceiveMessage(string message) проверяющим свойство объекта Control.InvokeRequired и в случае если обращение к элементу формы осуществляется из другого потока вызываем Control.Invoke с делегатом в качестве первого параметра, через второй параметр можно передать любой объект. ShowReceiveMessage можно безопасно вызывать в любом потоке.

Краткий листинг клиентского приложения


// Код доступа к свойствам объектов главной формы  из других потоков
delegate void UpdateReceiveDisplayDelegate(string message);
void ShowReceiveMessage(string message)
{
    if (listBox1.InvokeRequired == true)
    {
        UpdateReceiveDisplayDelegate rdd = 
			new UpdateReceiveDisplayDelegate(ShowReceiveMessage);

        // Ищем поток формы который владеет объектом
        // listBox1 и вызываем делегат rdd
        Invoke(rdd, new object[] { message });
    }
    else
    {
        // Если не требуется вызывать метод Invoke, 
        // обратимся напрямую к элементу формы.
        listBox1.Items.Add(message);
    }
}

Инструменты программирования и исходник

Примечание. Исходник отправки сообщений по протоколу TCP тестировался в Microsoft Visual Studio 2010, Операционная система Windows, .NET Framework 3.5 выше. При необходимости проект исходного кода конвертируется для работы в MS Visual Studio 2008.

Файл загрузки Размер Кол-во загрузок
tcpclientservertextmessage_vs11.zip 💾 50Кбайт 4070