Созданные ответы форума
-
АвторСообщения
-
tyman, скажи а как ты сделал так: ( не знаю как правильно сформулировать)
Вот допустим у нас 5 клиентов и у каждого отоброжается кружочек(игрок) и 4 других кружочка(игрока)
у каждого игрока есть координата X и Y и когда игрок передвигается то координаты передаются на сервер.
каким образом сервер передает одному из клиентов координаты других 4 игроков. если переменные X и Y всего по одной
Неужели нужно серверу создавать еще и x1 y1, x2 y2, и т.д ( а если их не 5 а 500) Как у тебя? И как вообще это осуществить? Может где описано?? Сама архитектура…Я рылся но не нашел
Я думаю что если долго пыхтеть над какой либо проблемой то ты с ней справишься, или же следует полностью поменять архитектуру приема передачи данных.
Ну возьми тот код что я скинул по твоей просьбе
пакет пришел>>рапаковка>> переменную x +1 >>запаковка>> отправка
Ну вот смотри) Надеюсь тебе что нибудь да и поможет. КОД НЕ ДОРАБОТАН.
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167#include <SFML/Graphics.hpp>#include <SFML/Network.hpp>#include <SFML/Graphics/Text.hpp>#include <SFML/System/String.hpp>#include <SFML/System/Time.hpp>#include <SFML/Network/IpAddress.hpp>#include <iostream>#include <list>#include <string>using namespace std;using namespace sf;struct List{IpAddress ip; //список ип адресовint port; // список портовIpAddress isip; //ип адрес на проверкуint isport; // ...Packet packet;List *Next, *Head;};void Add(IpAddress ip, int port, List *&MyList){List *temp = new List;temp->ip = ip;temp->port = port;temp->Next = MyList->Head;MyList->Head = temp;}void Send(List *MyList, IpAddress isip, int isport, Packet packet){UdpSocket socket;// Функция которая отправляет Пакеты всем кроме отправителяList *temp = MyList->Head;while (temp != NULL){if (temp->ip != isip || temp->port != isport){socket.send(packet, temp->ip, temp->port);packet.clear();}temp = temp->Next;}}void Show(List *MyList){List *temp = MyList->Head;while (temp != NULL){cout << temp->ip << ":" << temp->port << endl;temp = temp->Next;}}void Proof(List *MyList,IpAddress isip,int isport){// Не доработанная функция сверки и добавления клиентов в списокList *temp = MyList->Head;if (temp == NULL){Add(isip, isport, MyList);}else{while (temp != NULL){/*Почему не доработанная?еслиif (temp->ip != isip && temp->port != isport)то 1.1.1.1:20015 и 1.1.1.1:20025не добаляетеслиif (temp->ip != isip || temp->port != isport)то при сверке 1.1.1.1:20015 и 1.1.1.1:20025добавляет но при следующем заходе в функцию1.1.1.1:200151.1.1.1:200251.1.1.1:200251.1.1.1:200251.1.1.1:20025получается такая хрень в спискепоскольку уже имеещиеся1.1.1.1:20025он сравнивает с1.1.1.1:20015и добаляет от того получается клон который засоряет память*/if (temp->ip != isip && temp->port != isport){Add(isip,isport, MyList);}temp = temp->Next;}}}void ClearList(List *MyList){while (MyList->Head != NULL){List *temp = MyList->Head->Next;delete MyList->Head;MyList->Head = temp;}}int main() {setlocale(LC_ALL, "");//Выделяем память для стекаList *MyList = new List;MyList->Head = NULL; //инициализируем первый элемент// Создание соккета (UDP) и привязка портаUdpSocket socket;socket.bind(55002);socket.setBlocking(false);// Создание пакета, с помощью которого можно будет общатся с клиентомPacket packet;// Запрос и вывод СВОЕГО Ip адресаIpAddress ip = IpAddress::getLocalAddress();cout << "Server created with ip: " << ip << ":" << socket.getLocalPort() << endl;// Буфер Хуюферstring name;string buffer = "Подключено к серверу!";bool p = true;std::size_t received = 0;// Ип адресс отправителя и портIpAddress sender;unsigned short port;while (true){if (socket.receive(packet, sender, port) == sf::Socket::Done){packet >> buffer >> name;if (buffer != "")cout << name << ": " << buffer << endl;Proof(MyList, sender, port); // сверкаpacket << buffer << name; //распаковка//socket.send(packet, sender, port);Send(MyList, sender, port, packet);packet.clear();// показываем список если в буфере xif (buffer == "x" || buffer == 'x'){Show(MyList);}}sleep(sf::milliseconds(10));//Задержка}// сюда никогда не заходит ( еще до этого не дошел)ClearList(MyList); //Очищаем память.delete MyList->Head;delete MyList;system("pause");return 0;}КЛИЕНТ
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960#include <SFML/Graphics.hpp>#include <SFML/Network.hpp>#include <SFML/Graphics/Text.hpp>#include <SFML/System/String.hpp>#include <SFML/Network/IpAddress.hpp>#include <iostream>#include <list>#include <string>#include <conio.h>using namespace std;using namespace sf;int main() {setlocale(LC_ALL, "");string Mname;string name;// Создание соккета (UDP) и привязка портаsf::UdpSocket socket;socket.bind(55045);socket.setBlocking(false);// Создание пакета, с помощью которого можно будет общатся с клиентомPacket packet;// Буфер ХуюферIpAddress ip = IpAddress::getLocalAddress();string buffer = "Клиент подключился: " + ip.toString();cout << "Введите имя: ";cin >> Mname;// Ип адресс отправителя и портsf::IpAddress sender;unsigned short port;packet << buffer << Mname;socket.send(packet, "192.168.43.3", 55002);while (true){if (_kbhit()){cout << "Do it: ";cin >> buffer ;packet << buffer << Mname;socket.send(packet, "192.168.43.3", 55002); //Отправка данныхpacket.clear();buffer.clear();}if (socket.receive(packet, sender, port) == sf::Socket::Done){packet >> buffer >> name;if (buffer != "")cout << name << ": " << buffer << endl;}sleep(sf::milliseconds(10));//Задержка}system("pause");return 0;}Да уж, 50 строк кода удалено и заменено на 1) Спасибо)
А разве это проканает с UDP???
Не могу решить проблем.
socket.recieve(); программа замирает в этом месте если нету принятых пакетов.
думал что if (socket.recieve() != sf::Socket::Done)
исправит это но нифига, все равно программа останавливается в этом месте и ждет пакета, может есть варианты??
1. На виртуальных серверах ограниченое количество подключений tcp. Здесь выгодней udp так как не надо резервировать места.
Тут ты имеешь ввиду хостинг??
2. У меня сервер генерировал карту и отправлял клиенту. Нужно передать всю карту, mas[45][45]. Отправлял цыклом, по 45 элементов за передачу. Если масив 46×46 то 46-тая передача не доходила. Клиент знает, что должно прийти 46 писем, по 46 элементов, по этому ждёт, а сервер пишет, что все отправлено. Тут надо быть окуратным.
А ты уверен что карта должна генерироватся на сервере?? Мне кажется что это не целесообразно, как по мне карта генерируется у клиента и все обьекты. и при запросе клиента сервер говорит есть ли некий обьект на карте (моб,дерево,трава) или же нету. Хотя это зависит от твоей задачи, наверно.
Такой вопрос, как ты сделал (если сделал) такую функцию
Клиент 1 >> Сервер
Cервер >> Клиент 2, 3, 4 …
А ты с чем мучаешься TCP/UDP?
Я до этого не дошел, но мне кажется что пинговать сервер/клиент (чтобы знать есть клиент или нету) нужно через некий отдельный канал. то есть: клиент отправляет (в цикле естественно) конкретный пакет! А на сервере его сравнивать. допустим если клиент отправил пакет и этот пакет == нашему пакету. то не удалять из списка.
1. Если ты отправляешь данные, а клиент не принимает то программа стоит афк.
Вот этого не понял , с кодом может быть пойму. Может у тебя проблема с ожиданием
ведь если у сервера/клиента в цикле такая строка то программа замирает пока не получит пакет и строки дальше не читаются.
C++1socket.receive(packet, sender, port);Но это можно легко исправить таким if`ом
C++1234if (socket.receive(packet, sender, port) == sf::Socket::Done){cout << "если пакет получен, то ...";}И тогда даже если пакет не пришел то выполнение кода не стоит а продолжается.
2. При передаче матрицы int больше 45×45 последние строки не передается. Сервер пишет, что отправил, а клиент ждет приема.
Опиши тут то я точно не понял. Массив[45][45]?
А передача частями?
В документации были какие-то розетки с таймером ожидания передачи, но я так и не понял как ними пользоваться, по этому оптимальным есть передавать данные тому кто просит, а не всем по списку.
Можно ссылку. по документации вообще нужно быть осторожным, я оттуда код скописатил, а там была в какойто сторке ошибка имени переменной Func — func как то так. И я 2 часа мучался, и библиотеки подключал( что я короче не делал) но нашел))) злой был пи….ц!)
А вот по поводу Розеток(socket) мне кажется это касалось TCP. Но не уверен.
Да, спасибо! Ты был прав по поводу Ip я не знал что что можно так сделать. Если бы ты не подсказал пришлось бы переводить string в ip, каким нибудь образом)
А что же тогда использовать вместо string??
C++1234567891011void Proof(List *MyList,string isip,int isport){List *temp = MyList->Head;while (temp != NULL){if (temp->ip != isip || temp->port != isport){Add(isip,isport, MyList);}return;}Вот функция которая проверяет и добавляет нового клиента в список.
Как по мне это оптимальный вариант, я не знаю что можно использовать вместо string.
Ведь Ip (0.0.0.0) не целочисленный тип а кроме как string лучше варианта не вижу, поскольку не знаю..
С таймером понял, но его пока не делал. Наверное сейчас буду реализовывать.
Спасибо) Сделал через список, правда для ип адресса использовал string, но я не понял зачем тут таймер, можешь обьяснить?
Если у кого нибудь возник такой же вопрос ( как запихнуть в список ип адреса) то вот рабочий код
C++123456789101112131415161718192021222324252627282930313233struct List{string ip;int port;List *Next, *Head;};void Add(string ip, int port, List *&MyList){List *temp = new List;temp->ip = ip;temp->port = port;temp->Next = MyList->Head;MyList->Head = temp;}void Show(List *MyList){List *temp = MyList->Head;while (temp != NULL){cout << temp->ip << ":" << temp->port << endl;temp = temp->Next;}}void ClearList(List *MyList){while (MyList->Head != NULL){List *temp = MyList->Head->Next;delete MyList->Head;MyList->Head = temp;}}Чтобы получить Ип в клиенте вам нужно отправить данные на сервер (любые)
socket.receive(buffer, sizeof(buffer), received, sender, port);
таким образом принимаем сообщение и добавляем в список
Add(sender.toString(), port, MyList);
Если у кого есть идеи получше пишите)
Вопрос еще Актуален?
Эти функции возвращают Ип адресс той программы в которой они используются, а мне нужно На стороне сервера узнать подключенных клиентов.
C++123456789101112131415161718192021UdpSocket socket;socket.bind(55002);// Создание пакета, с помощью которого можно будет общатся с клиентомPacket packet;// Запрос и вывод СВОЕГО Ip адресаIpAddress ip = IpAddress::getLocalAddress();cout << "Server created with ip: " << ip << endl;char buffer[1024];std::size_t received = 0;IpAddress sender;unsigned short port;// Прием первого сообщения от клиента с Ип адресомsocket.receive(buffer, sizeof(buffer), received, sender, port);cout << buffer << ":" << port << std::endl;// Отправка клиенту успешного подключенияstd::string message = "Connected to " + sender.toString();socket.send(message.c_str(), message.size() + 1, sender, port);cout << "blalala: " << ip << ":" << port << endl;cout << socket.getLocalPort();Вот как тут видно, я получаю сообщение от клиента и тем самым могу узнать его ип и порт. Но от этого легче не стало..
Поскольку появился ряд вопросов.
Как сделать список клиентов?
Как узнать отключился ли клиент?
Как отсылать всем клиентам сообщения?
C++12345678910111213141516171819while (true){socket.receive(buffer, sizeof(buffer), received, sender, port);packet >> buffer;cout << "Client: " << buffer << endl;packet << buffer; //Пакуем значения координат в Пакетsocket.send(buffer, sizeof(buffer) + 1, sender, port); //Отправка данныхpacket.clear(); //Чистим пакетsleep(sf::milliseconds(10));//Задержка}Как видно из цикла то при получении сообщения от клиента, я могу отправить только ему обратное сообщение.
Действует некий прицип
Клиент1 >> Сервер
Сервер >> Клиент1
Но если подключится еще один клиент то получается так
Клиент1 >> Сервер
Сервер >> Клиент1
Клиент2 >> Сервер
Сервер >>Клиент 1
А мне нужно что бы сервер работал со всеми клиентами и отправлял пакеты всем клиентам
Клиент1 >> Сервер
Сервер >> Клиент2, Клиент3, Клиент16….
Для этого нужно сделать Массив Ип адресов ну или список, но немогу понять как???
C++1sf::IpAddress sender;как сделать список?
Код много раз редактировался. Прошу на многие нелепости не обращать внимание.
-
АвторСообщения