Простейшие коды клиент-сервера UDP - C#
Формулировка задачи:
Собственно, вопрос избитый уверен. Помогите, плиз, разобраться.
Пишу контрольную.
Простейшие коды клиент-сервера UDP:
Клиент:
Сервер:
Вроде все хорошо, однако, при подключении более одного клиента видно, что сервер отправляет сообщение (не широковещательное) а именно тому клиенту от которого получил сообщение.
Как сделать так, чтоб сервер отсылал в сеть сообщения всем клиентам.
Подключаю клиенты прямо с локалхоста. При отладке вижу, что отличаются порты.
Уверен, что проблема в том, что я чего-то недопонимаю. В поиске был - толи чего-то опять упустил, либо просто не нашел подходящей инфы.
Не пинайте, плиз сильно - помогите советом.
Спасибо.
using System; using System.Net; using System.Net.Sockets; using System.Text; public class Udp_Client { public static void Main() { byte[] data = new byte[1024]; string input, stringData; //Ввод IP-адреса сервера Console.Write("Укажите IP-адрес сервера: "); string addr = Console.ReadLine(); //Если адрес пустой - принимаем за локалхост if (addr == "") addr = "127.0.0.1"; //Создание нового UDP-клиента и установка удаленного узла по умолчанию UdpClient server = new UdpClient(addr, 9050); //создаем конечную точку по адресу сокета. Т.е. будем "слушать" порты //и контролировать все сетевые интерфейсы IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); //Отправляем серверу сообщение о подключении string welcome = "Клиент успешно подключился!"; data = Encoding.UTF8.GetBytes(welcome); server.Send(data, data.Length); //От сервера придут данные, типа "Подключение успешно" data = server.Receive(ref sender); //Обеспечиваем их отображение на экране Console.Write("Сообщение принято от {0}:", sender.ToString()); stringData = Encoding.UTF8.GetString(data, 0, data.Length); Console.WriteLine(stringData); //Бесконечный цикл. while (true) { //Объявляем новый массив под пришедшие данные. data = new byte[1024]; //Ожидаем ввода с клавиатуры (строки) и заносим в переменную input Console.Write("\r\n>"); input = Console.ReadLine(); //Перевод отсылаемой строки в байты data = Encoding.UTF8.GetBytes(input); //Отсылаем серверу строку (переведенную в байты) server.Send(data, data.Length); //Если пришла команла exit - выходим из цикла (далее - закрываем сокет и т.д.) if (input == "exit") break; //Получение данных... data = server.Receive(ref sender); //Перевод принятых байтов в строку stringData = Encoding.UTF8.GetString(data, 0, data.Length); Console.Write("<"); //Отображение на экране принятой строки (размер файла) Console.WriteLine(stringData); } //После выхода из цикла... Console.WriteLine("Остановка клиента..."); //Закрываем UDP-соединение server.Close(); } }
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.IO; public class UDP_Server { public static void Main() { int recv; byte[] data = new byte[1024]; //Сетевая конечная точка в виде адреса и номера порта IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050); //Создание нового сокета (схема адресации, тип сокета, протокол) //параметр AddressFamily задает схему адресации. В нашем случае это адреса IPv4 //параметр SocketType указывает, какой тип сокета применяется. //Datagram - поддерживает двусторонний поток данных. Не гарантируется, что этот поток будет последовательным, //надежным, и что данные не будут дублироваться. Важной характеристикой данного сокета является то, //что границы записи данных предопределены. //последний параметр, ProtocolType, задает тип протокола Socket SrvSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //Связываем новый сокет с локальной конечной точкой SrvSock.Bind(ipep); Console.WriteLine("Ожидаем соединения с клиентом..."); //создаем конечную точку по адресу сокета. Т.е. будем "слушать" порты //и контролировать все сетевые интерфейсы IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); //Получаем конечную удаленную точку EndPoint Remote = (EndPoint)(sender); //Получаем сообщение от клиента (типа, "Клиент успешно подключился!") recv = SrvSock.ReceiveFrom(data, ref Remote); //Отображаем сообщение о успешно подключенном клиенте Console.Write("Сообщение получено от {0}:", Remote.ToString()); Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv)); //Отправляем клиенту сообщение об успешном подключении string welcome = "Подключение к серверу успешно!"; data = Encoding.UTF8.GetBytes(welcome); SrvSock.SendTo(data, data.Length, SocketFlags.None, Remote); //Бесконечный цикл. while (true) { //Объявляем новый массив под пришедшие данные. data = new byte[1024]; //Получение данных... recv = SrvSock.ReceiveFrom(data, ref Remote); //Перевод принятых байтов в строку string str = Encoding.UTF8.GetString(data, 0, recv); //Если пришла команда выхода //Завершаем работу сокета и программы... if (str == "exit") break; Console.WriteLine("Получили данные: " + str); //Записываем в переменную size новый размер файла (после процедуры prntofile) double size = prntofile(str); //Отображаем форматированное сообщение string input = "Строка успешно записана!\nНовый размер файла: " + size + " байт."; Console.WriteLine(">" + input + "\n"); //Перевод отсылаемой строки в байты data = Encoding.UTF8.GetBytes(input); //Отсылаем серверу строку (переведенную в байты) SrvSock.SendTo(data, data.Length, SocketFlags.None, Remote); } } //Процедура записи в файл и вычисления размера public static double prntofile(string str) { //Определяем имя файла string fil = "Mystr_Srv.txt"; StreamWriter sw; FileInfo fi = new FileInfo(fil); //Открываем файл на appendtext sw = fi.AppendText(); //Записываем в файл строку sw.WriteLine(str); //Закрываем файл. sw.Close(); //Вычисляем размер файла (в байтах). double size = fi.Length; //Возвращаем размер файла. return size; } }
Решение задачи: «Простейшие коды клиент-сервера UDP»
textual
Листинг программы
Console.WriteLine(stringData);
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д