SFML и C++ Уроки \ Разработка игр › Форумы › SFML Network › Ряд вопросов
В этой теме 23 ответа, 5 участников, последнее обновление tyman 7 года/лет, 1 месяц назад.
-
АвторСообщения
-
mypmyp, не посмотрел, что вы UDP сокеты используете. Тогда все еще проще, перейдите в не блокирующий режим udpSocket.setBlocking(false);
Да уж, 50 строк кода удалено и заменено на 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;}Пинг штука страшная, видно как пакеты теряются на глазах.
У меня сервер обрабатывал все данные, если ты нажал в лево, то на сервер отправлено букву с направлением, сервер ходил тем персонажем и отправлял положение всех персонажей обратно. Но дело было так:
Когда подключался к серверу я, все работало как часы.
Когда подключался второй игрок, то он отставал, мой персонаж бегал быстрее.
Когда подключался третий, лагало словно из Европы в Китай.
Я думаю что если долго пыхтеть над какой либо проблемой то ты с ней справишься, или же следует полностью поменять архитектуру приема передачи данных.
Пользуясь UDP не забывайте проверять пакеты на максимально возможный размер MaxDatagramSize
tyman, скажи а как ты сделал так: ( не знаю как правильно сформулировать)
Вот допустим у нас 5 клиентов и у каждого отоброжается кружочек(игрок) и 4 других кружочка(игрока)
у каждого игрока есть координата X и Y и когда игрок передвигается то координаты передаются на сервер.
каким образом сервер передает одному из клиентов координаты других 4 игроков. если переменные X и Y всего по одной
Неужели нужно серверу создавать еще и x1 y1, x2 y2, и т.д ( а если их не 5 а 500) Как у тебя? И как вообще это осуществить? Может где описано?? Сама архитектура…Я рылся но не нашел
Значит так. На сервере Был список с пользователями:
struct user{
String name;
int x, y;
user *next;
};
Когда кто то ходил, то на сервер приходил пакет: {
int state; //Чего хочет клиент: 1-регистрация, 2-ход, 3-ожидание
String name;//Имя
char nap;//Направление W, S, A, D
};Если регистрация то сервер проверял имя(на занятость), отправлял размер карты и саму карту;
Если ход то проверял имя, двигал фигурку(проверяло на стены), отправлял данные назад;
Если ожидание то отправлял данные;Данные которые сервер отправлял назад выглядели:
Первый пакет содержал количество пользователей;
А дальше отправлялись имена и координаторы;В клиенте всё это добро выставлялось на экран;
Камера выставлялась на координатах того кто имел клиентское имя; -
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.