static void Main(string[] args)

        {
            Console.ForegroundColor = ConsoleColor.Yellow;

            Console.WriteLine(new string('_', 55) + "PROGRAMM" + new string('_', 55) + "\n");

            Console.ResetColor();

            choose : Console.WriteLine("Please choose which service to use - TCP(1) or UDP(2).If you want to change the protocol, write -other protocol- \n");

            start : string ch = Console.ReadLine();

            if (ch == "1")

            {
                try

                {
                    TcpClient client = new TcpClient();

                    client.SendTimeout = 1000;

                    client.Connect("127.0.0.1", 8001);



                    byte[] data = new byte[256];

                    StringBuilder response = new StringBuilder();

                    NetworkStream stream = client.GetStream();



                    //Connection confirming

                    do

                    {
                        int bytes = stream.Read(data, 0, data.Length);

                        response.Append(Encoding.UTF8.GetString(data, 0, bytes));
                    }while (stream.DataAvailable);



                    Console.WriteLine(response.ToString());

                    Console.WriteLine("Enter operations in this format : NUMBER space OPERATOR space NUMBER");



                    string message = String.Empty;



                    do

                    {
                        if (message == "other protocol")

                        {
                            stream.Close();

                            client.Close();

                            goto choose;
                        }

                        message = Console.ReadLine();

                        byte[] data1 = Encoding.UTF8.GetBytes(message);

                        stream.Write(data1, 0, data1.Length);



                        StringBuilder result = new StringBuilder();

                        var data2 = new byte[256];

                        int bytes = stream.Read(data2, 0, data2.Length);

                        result.Append(Encoding.UTF8.GetString(data2, 0, bytes));

                        Console.WriteLine("Result = " + result);
                    }while (message != String.Empty);



                    stream.Close();

                    client.Close();
                }

                catch (Exception e)

                {
                    Console.WriteLine("Something goes wrong...disconnected");
                }
            }

            else if (ch == "2")

            {
                Console.Clear();



                Console.WriteLine("WELCOME \nEnter operations in this format : NUMBER space OPERATOR space NUMBER");



                //for sending

                UdpClient client = new UdpClient();

                client.Connect("localhost", 1000);



                //for getting

                UdpClient udpClient = new UdpClient();

                udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 8001));



                try

                {
                    IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);



                    string message = String.Empty;        //this object must be sent to the server

                    string result = String.Empty;         //this object must be received from server



                    do

                    {
                        //Sending to Math server

                        message = Console.ReadLine();



                        if (message == "other protocol")

                        {
                            client.Close();

                            goto choose;
                        }



                        var sendBytes = Encoding.ASCII.GetBytes(message);

                        client.Send(sendBytes, sendBytes.Length);



                        //Receiving result from math server

                        var receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);

                        result = Encoding.ASCII.GetString(receiveBytes);

                        Console.WriteLine("Result = " + result);
                    }while (message != String.Empty);



                    client.Close();
                }

                catch (Exception e)

                {
                    Console.WriteLine("Something goes wrong...disconnected");

                    return;
                }
            }

            else

            {
                goto start;
            }
        }
        //Содерэит логику поиска сервера. Сервер может находиться на любом компьютере в локальной сети
        //И надо как-то выяснить, где именно. Поэтому мы опросим все комрьютеры,
        //И если на каком-то из них есть сервер, он даст о себе знать
        //Так же мы будем ждать сервер, если не можем его найти
        public void FindServer()
        {
            //Данные, которые мы будем рассылать в широковещательном UDP сообщении
            //Будем отсылвать 1 байт, просто потому что. В этом нет какой-то логики
            //Можем не отсылать данных вообще.
            //Так же в эту же переменнаю будут записаны данные, которые мы получим от сервера.
            //А именно - TCP порт сервера
            var data = new byte[] { 1 };
            //Сервер, если он есть в локальной сети, слушает UDP сообщения на 5000 порту
            //Потому мы быдем отсылать сообшение всем, на порт 5000
            var endPoint = new IPEndPoint(IPAddress.Broadcast, 5000);
            //Номер попытки нахождения сервера. То есть мы первый раз отправляем сообщение о поиске сервера
            int tryNum = 1;
            //Создаем формочку, которая будет отображать пользователю информацию, что мы 1 раз
            //Пытаемся подключиться к серверу.
            //Это нужно для того, чтобы в ситуации когда сервера нет, и мы пробуем найти его снова и снова,
            //Пользователь видел, что программа не висит, и все нормально
            var placeHolder = new PlaceHolderWrapper($"Finding server try #{tryNum}");
            //Сохдаем объект для отправки и приема данных по протоколу UDP
            //ОС сама выберет порт, на котором будет работать этот клиент, потому не передаем
            //аргументов в конструктор
            var udpClient = new UdpClient();

            //Устанавливаем, что данный клиент будет ждать сообщений только 1000 милисекунд
            //Если данных нет в течении 1000 секунд - будет брошено исключение
            //Сделано для того чтобы мы могли отослать новое сообщение, если на старое никто не ответил
            //Ведь сервер может быть запущен позже, чем клиент
            udpClient.Client.ReceiveTimeout = 1000;
            //Условно бесконечный цикл. Сам цикл будет работать вечно, но внутрянняя логика
            //Прервет его выполнение в необходимый момент
            while (true)
            {
                //Если код внутри блока try выбросит исключение, выполнение перейдет в блок catch
                //И мы сможем предпринять какие-то действия, обработать эту ситуацию
                //В данном случае, мы можем получить исключение времени ожидания,
                //Понять, что переходим на следующую итерацию, уведомить про это пользователя,
                //И послать новое сообщение
                try
                {
                    //Отправляем сообщение длиной в 1 байт всем пк на порт 5000
                    udpClient.Send(data, data.Length, endPoint);
                    //Ждем, когда сервер вернет нам свой порт.
                    //Если сервер прислал порт, он будет записан в массив data в виде 4-х байт
                    //В переменную endPoint запишется адресс сервера, откуда нам пришло сообщение
                    //Это и есть адрес сервера. Ведь он отправит нам ответ
                    data = udpClient.Receive(ref endPoint);
                    //заканчиваем цикл while, мы получили TCP порт, так что пора к нему присоединяться
                    break;
                }
                //В течении секунды не пришло сообщения
                catch
                {
                    //Увеличиваем счетчик попыток на 1
                    tryNum++;
                    //У нашей формы заглушки устанавливаем новый текст для отображения
                    //Так, при каждой попытке мы увидим на консоли ее номер
                    placeHolder.Content = $"Finding server try #{tryNum}";
                }
            }
            //Отчищаем UDP клиента, он нам больше не понадобится
            //метод Dispose освободит занятый порт
            udpClient.Dispose();
            //Получаем число, порт сервера, из байт, которые он нам прислал
            //Чило, а именно порт сервера, хранится в переменной типв=а int
            //Допустим, порт сервера это 5100
            //По сети могут быть переданы только байты, потому данные биты (нули и единицы)
            //Разбиваются на 4 байта. Почему 4? int занимает 32 бита
            //А один байт занимает 8 бит. Соответственно любое число типа int может быть разбито на 4 байта
            //Нам же надо склеить эти байты обратно в int переменнную
            //BitConverter умеет отдавать байты для конкретного числа и создавать число из байт.
            //Смело пользуемся им
            int targetPort = BitConverter.ToInt32(data, 0);

            //Устанавливаем соединение с сервером. его IP адрес мы получили при получении UDP сообщения
            tcpClient.Connect(endPoint.Address, targetPort);
            //Запускаем метод ListenConnectioin, этот метод будет слушать данные от сервера, и вызывать
            //Событие о том, что пришел какой-то отсет от сервера. Все, кто захотят об этом узнать - узнают
            Task.Factory.StartNew(ListenConnection);
        }
Exemple #3
0
 public void Send(string text, string ip, int port)
 {
     ClientSend.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
     byte[] data = Encoding.ASCII.GetBytes(text);
     ClientSend.Send(data, data.Length);
 }