Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.IO;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Net;
- using System.Net.Sockets;
- namespace server
- {
- class programm
- {
- static int[,] g = new int[5, 5]; //граф остановок в элементе g[i,j] хранится расстояние от i до j в графе остановок
- static float cst = 0.5F; //цена за единицу пути
- static float v = 1; //средняя скорость автобуса
- static int client_port = 8048; //порнт на который приходят соединения клиента
- static int bus_port = 8049; //порт на который приходят соежинения автобусов
- static string adress = "127.0.0.1";
- static string path = @"C:\Users\Кирилл\source\repos\str_bus\str_bus\graph.txt";
- static void Main()
- {
- read_graph();
- IPEndPoint client_ipPoint = new IPEndPoint(IPAddress.Parse(adress), client_port);
- IPEndPoint bus_ipPoint = new IPEndPoint(IPAddress.Parse(adress), bus_port);
- Socket bus_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- Socket client_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- try
- {
- bus_sock.Bind(bus_ipPoint);
- bus_sock.Listen(1);
- client_sock.Bind(client_ipPoint);
- client_sock.Listen(1);
- Console.WriteLine("Включен режим прослушивания");
- List<Bus> buses = new List<Bus>();
- while (true)
- {
- foreach (Bus bus in buses)
- {
- bus.update_loc(); //Обновление местоположения уже работающих автобусов
- Console.WriteLine("Местоположение автобусов обновленно");
- }
- if (bus_sock.Poll(0, SelectMode.SelectRead))
- {
- buses.Add(new Bus(bus_sock.Accept())); //добавление к списку ещё одного активного автобуса
- Console.WriteLine("Добавлен новый автобус");
- }
- Pasanger pas = new Pasanger(client_sock.Accept()); //приём запроса пассажира
- Console.WriteLine("Добавлен новый пассажир");
- Bus b = new Bus();
- Pair v = check_dist(b, buses, pas); //Расчет наилучшего автобуса и вершин в пути автобуса от которых будет проложен путь к start и finish
- if (b != null)
- {
- Console.WriteLine("Найилучший автобус найден");
- Answer ans = new Answer();
- vector way = b.change_way(pas, v); //Изменение пути для пассажира
- Console.WriteLine("Изменение пути расчитано");
- int S = calc_dist(way, pas.od); //Рассчет расстояния между вершинами start и finish
- ans.coast = calc_coast(S); //Рассчет стоймости поездки
- ans.time = calc_coast(S);
- ans.time = calc_time(S);
- ans.number = b.number;
- ans.flag = true;
- pas.send_data(ans); //Отправки данных пассажиру
- Console.WriteLine("Запрос подтверждения от пассажира");
- if (pas.conf()) //Ожидание ответа пассажира
- {
- Console.WriteLine("Подтверждение получено");
- b.Way = way;
- b.send_way(); //Отправка новго пути автобусу
- }
- }
- else
- {
- Console.WriteLine("Автобус не найден");
- Answer ans = new Answer();
- ans.flag = false;
- pas.send_data(ans);
- }
- }
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
- struct Answer
- {
- public bool flag; //положительный/отрицательный ответ
- public string number; //регистрационный номер автобуса
- public float coast; //цена поездки
- public float time; //время поездки
- public List<int> way; //Путь
- } //Структура ответа сервера
- struct Location
- {
- public int pos;
- /*float x;
- float y;*/
- } //структура местоположения
- struct Pair
- {
- public int start;
- public int finish;
- } //структура начала и конца пути
- class vector
- {
- int[] values;
- public int size;
- public vector()
- {
- values = new int[30];
- size = 0;
- }
- public void Add(int val)
- {
- values[size++] = val;
- }
- public void Del(int index)
- {
- for (int i = index + 1; i < size; i++)
- values[i - 1] = values[i];
- size--;
- }
- public int this[int index]
- {
- get { return values[index]; }
- set { values[index] = value; }
- }
- }
- class Bus
- {
- public string number; //Регистрационный номер автобуса
- Location loc; //Текущее местоположегние автобуса
- int num_pasn; //Кол-во пасажиров в автобусе
- public vector way; //Текущий путь автобуса
- bool active; //флаг состояния автобуса
- Socket socket; //дискриптор сокета автобуса
- private void recv()
- {
- StringBuilder dat = new StringBuilder();
- byte[] buff = new byte[256];
- int bytes = 0;
- do
- {
- bytes = socket.Receive(buff);
- dat.Append(Encoding.Unicode.GetString(buff, 0, bytes));
- } while (socket.Available > 0);
- int i = 0;
- while (dat[i] != ' ')
- number += dat[i++];
- string pos = "";
- i++;
- for (; i < dat.Length; i++)
- pos += dat[i];
- loc.pos = Convert.ToInt32(pos);
- }
- public vector Way
- {
- set
- {
- way = value;
- }
- } //свойство обновляющие way
- public Bus()
- {
- active = false;
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- }
- public Bus(Socket sock)
- {
- loc = new Location();
- num_pasn = 0;
- way = new vector();
- active = true;
- socket = sock;
- recv();
- } //Конструктор устанавливающий дискриптор и номер автобуса
- public vector change_way(Pasanger ps,Pair v)
- {
- int ds;
- vector res = new vector();
- for (int i = 0; i < way.size; i++)
- {
- if (way[i] == v.start)
- {
- res.Add(v.start);
- res.Add(ps.od.start);
- }
- else if(way[i] == v.finish)
- {
- res.Add(v.finish);
- res.Add(ps.od.finish);
- }
- else res.Add(way[i]);
- }
- return res;
- } //Возвращает текущий путь оптимально дополненый вершинами ps.start и ps.finish
- public void update_loc()
- {
- string message = "g";
- socket.Send(Encoding.Unicode.GetBytes(message));
- byte[] buff = new byte[256];
- int bytes = socket.Receive(buff);
- loc.pos = Convert.ToInt32(Encoding.Unicode.GetString(buff, 0, bytes));
- } //обновляет место положение автобуса
- public void send_way()
- {
- num_pasn++;
- string w = "";
- for (int i = 0; i < way.size; i++)
- w += Convert.ToString(way[i]) + " ";
- socket.Send(Encoding.Unicode.GetBytes(w));
- }
- }
- class Pasanger
- {
- public Pair od; //информауия о начале и конце пути
- Socket socket; //сокет через который происходит обмен данными
- public Pasanger(Socket sock) //конструктор получающий сокет из прослушающего сокета listener
- {
- socket = sock; //Получение сокета из очереди
- StringBuilder date = new StringBuilder();
- recv(date); //считываение переданных данных
- wr_date(date); //записывает данные в поля объекта
- }
- public void send_data(Answer ans)
- {
- String message = "";
- message += ans.flag ? "1" : "0" + " ";
- message += ans.coast.ToString() + " ";
- message += ans.time.ToString() + " ";
- message += ans.number + " ";
- foreach (int p in ans.way)
- message += p.ToString() + " ";
- byte[] data = new byte[256];
- data = Encoding.Unicode.GetBytes(message);
- socket.Send(data);
- } //преобразует данные из ans в строку и отправляет её клиенту
- public bool conf()
- {
- StringBuilder ans = new StringBuilder();
- recv(ans); //отправляет ans клиенту
- return ans.ToString() == "1" ? true : false;
- } //Получение подтвекрждение от клиента
- private void recv(StringBuilder data)
- {
- int bytes = 0;
- byte[] buf = new byte[256];
- do
- {
- bytes = socket.Receive(buf);
- data.Append(UnicodeEncoding.Unicode.GetString(buf, 0, bytes));
- } while (socket.Available > 0);
- Console.WriteLine(data.ToString());
- } //считывание данных полученных через pasanger.socket
- private void wr_date(StringBuilder date)
- {
- String st = "";
- String fin = "";
- int i = 0;
- while (date[i] != ' ')
- st += date[i++];
- i++;
- for (; i < date.Length; i++)
- fin += date[i];
- od.start = Convert.ToInt32(st);
- od.finish = Convert.ToInt32(fin);
- }//Преобразует строку StringBuilder в два числа и записывает их в поля объекта
- }
- static void read_graph()
- {
- using (StreamReader st = new StreamReader(path, System.Text.Encoding.Default))
- {
- string line;
- while ((line = st.ReadLine()) != null)
- {
- int i = 0;
- int u = get_int(line, ref i);
- int v = get_int(line, ref i);
- g[u, v] = get_int(line, ref i);
- }
- }
- }
- static int get_int(string str, ref int pos)
- {
- string res = "";
- while (str[pos] != ' ')
- res += str[pos++];
- pos++;
- return Convert.ToInt32(res);
- }
- static Pair check_dist(Bus b, List<Bus> buses, Pasanger ps)
- {
- int min = 1000000000;
- Pair res = new Pair { start = -1, finish = -1 };
- foreach (Bus bs in buses)
- {
- Pair v = new Pair();
- int dist = find_dist(bs.way, ps.od, v); //Расчет минимального отклонения от маршрута для текущего автобуса и вершин start и finish
- //Pair v = bs.near_point(ps.od.start, out dist);
- if (dist < min)
- {
- min = dist;
- b = bs;
- res = v;
- }
- }
- return res;
- } //ищет ближайший к пасажиру Ps автобус в списке buses
- static int find_dist(vector way, Pair ps, Pair prs)
- {
- bool flag = false;
- int res = (int)1e9;
- for (int i = 0; i < way.size; i++)
- {
- if ((g[way[i], ps.start] + g[ps.start, ps.finish] + g[ps.finish, way[i + 1]]) < res)
- {
- res = g[way[i], ps.start] + g[ps.start, ps.finish] + g[ps.finish, way[i + 1]];
- prs.start = way[i];
- prs.finish = way[i + 1];
- }
- else if ((res - g[ps.start, ps.finish] + g[ps.start, prs.start] + g[way[i], ps.finish] + g[ps.finish, way[i + 1]]) < res)
- {
- res = res - g[ps.start, ps.finish] + g[ps.start, prs.start] + g[way[i], ps.finish] + g[ps.finish, way[i + 1]];
- prs.finish = way[i];
- }
- }
- return res;
- } //возвращает расстояние между ps.start и ps.finish в way
- static float calc_coast(int S)
- {
- return S * cst;
- } //возвращает цену пути S
- static float calc_time(int S)
- {
- return S / v;
- } //возвращает время пути длины S
- static int calc_dist(vector way, Pair ps)
- {
- int i = 0;
- while (way[i] != ps.start)
- i++;
- int res = 0;
- while (way[i] != ps.finish)
- {
- res += g[way[i], way[i + 1]];
- i++;
- }
- return res;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement