SFML и C++ Уроки \ Разработка игр › Форумы › SFML Network › Пример реализации SFML Network
Помечено: Мессенджер
В этой теме 13 ответов, 7 участников, последнее обновление yur4ik 3 года/лет, 6 мес. назад.
-
АвторСообщения
-
Здравствуйте, хочу предложить один из вариантов как реализовать библиотеку Network, для этого необходимо её подключить:
C++1#include <SFML/Network.hpp>Далее задумка очень проста: есть 2 компьютера, один “Сервер-компьютер” второй “клиент-компьютер”. Первый создает по протоколу TCP подключение к себе, второй подключается к нему и производит какие то действия, в нашем случае двигает шарик по экрану.
Пример программы:
C++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798#include <SFML/Graphics.hpp>#include <SFML/Network.hpp>#include <iostream>#include <string>using namespace std;using namespace sf;int main() {setlocale(LC_ALL, ""); // Поддержка кириллицы в консоли WindowsIpAddress ip = IpAddress::getLocalAddress(); //Локальный ip АдрессTcpSocket socket;//программный интерфейс для обеспечения обмена данными между процессамиPacket packet; //Для осуществления пакетной передачи дынныхchar type;char mode = ' ';//Мод s- сервер, с - клиентint x = 0; //координаты шараint y = 0;char buffer[2000];size_t received; //??string text = "connect to: ";//***********Подключение***************//cout << ip << endl;cout << "Введите тип подключения: c -клиент, s -сервер" << endl;cin >> type;if(type == 's'){TcpListener listener;listener.listen(2000);listener.accept(socket); //который будет содержать новое соединениеtext += "Serwer";mode = 's';} else if(type == 'c'){cout << "new ip:";cin >> ip;socket.connect(ip, 2000); //ip и Портtext += "client";mode = 'r';}socket.send(text.c_str(), text.length() + 1);socket.receive(buffer, sizeof(buffer), received);cout << buffer <<endl;//**********Отрисовка Формы***********************//RenderWindow window(sf::VideoMode(800, 600), "Network");//Создаем размер Главного окна//*******Элементы********************//CircleShape shape(10); //создаем шар с радиусом 50while(window.isOpen()){sf::Event event;while(window.pollEvent(event)){if(event.type == sf::Event::Closed){window.close();}}if(mode == 's'){socket.receive(packet); //Команда которая ожидает данных в виде пакета от клиентской частиif(packet >> x >> y){ //вытаскиваем значение из пакета в переменную x и у (действие уже происходит)cout << x << ":" << y<< endl; //..и если все прошло успешно то выводим её координаты}}if(mode == 'r'){if (Keyboard::isKeyPressed(Keyboard::Right)) { //первая координата Х отрицательна =>идём влевоx ++;}if (Keyboard::isKeyPressed(Keyboard::Left)) { //первая координата Х отрицательна =>идём влевоx --;}if (Keyboard::isKeyPressed(Keyboard::Down)) { //первая координата Х отрицательна =>идём влевоy ++;}if (Keyboard::isKeyPressed(Keyboard::Up)) { //первая координата Х отрицательна =>идём влевоy --;}packet << x << y; //Пакуем значения координат в Пакетsocket.send(packet); //Отправка данныхpacket.clear(); //Чистим пакет}window.clear();shape.setPosition(x, y); //выставляем шар на координатыwindow.draw(shape); //отрисовываем шарwindow.display();sleep(sf::milliseconds(10));//Задержка}//ENDsystem("pause");return 0;}Если нет второго компьютера вы можете создать и на одном открыв приложение 2 раза.
Для подключения в интернете “Сервер-компьютер” должен открыть порт 2000 и в настройках роутера: NAT>DZM host> Использовать> Выбрать сетевой адрес хоста.
P.S. IDE Eclipse, компилятор MinGW
P.S.S если возникли трудности с компиляцией предоставляю готовую программу.
спасибо большое за столь ценный пост. К сожалению вложение слишком большое, поэтому не прикрепилось. У нас не так много памяти, чтобы загружать большие вложения:(
Можно пользоваться ссылками на облако, в том числе можно использовать для этого наше облако на яндекс диске из sfml_cloud
p.s после ценных постов так и хочется быстрее запилить на форум систему рейтинга:-)Крашится то клиент то вместе с сервером на моменте выбора режима клиент.
точка останова здесь cin >> ip;
Необработанное исключение по адресу 0x62B5F958 (msvcp120.dll) в SFML Network.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCDCDCDCD.
Это у меня проблемы с подключением библиотеки sfml. Очень странные проблемы, не хочет не в какую подключаться . Видимо это новые приколы от Visual Studio 15 RC , а так все работает, + автору ) (компильнул через Visual Studio 13 )
Я тут нафлудил )) за ранее извиняюсь. Но по чему такая задержка ?
задержка ответа? 10 сек должна быть
В скорости передачи и обработки пакетов. Я убрал 10 миллисекунд из кода, но по ощущениям как будто сервер в китае а я где нибудь в польше )
Я думал ты про задержку отправки сообщений на форуме)
Ухты, круто! Но к этому я вернусь позже
Я заметил проблему о задержке сервера, я ее решил таким образом
if(mode == ‘s’){
socket.receive(packet); //Команда которая ожидает данных в виде пакета от клиентской части
if(packet >> x >> y){ //вытаскиваем значение из пакета в переменную x и у (действие уже происходит)
cout << x << “:” << y<< endl; //..и если все прошло успешно то выводим её координаты
}
}if(mode == ‘r’){
if (Keyboard::isKeyPressed(Keyboard::Right)) { //первая координата Х отрицательна =>идём влево
x ++;
}
if (Keyboard::isKeyPressed(Keyboard::Left)) { //первая координата Х отрицательна =>идём влево
x –;
}if (Keyboard::isKeyPressed(Keyboard::Down)) { //первая координата Х отрицательна =>идём влево
y ++;
}
if (Keyboard::isKeyPressed(Keyboard::Up)) { //первая координата Х отрицательна =>идём влево
y –;
}packet << x << y; //Пакуем значения координат в Пакет
socket.send(packet); //Отправка данных
packet.clear(); //Чистим пакет
}
window.clear();
shape.setPosition(x, y); //выставляем шар на координаты
window.draw(shape); //отрисовываем шар
window.display();
if(mode == ‘r’)
sleep(sf::milliseconds(10));//Задержка
}//ENDТо есть я заметил сервер все время начал позже показывать действия, как я понял сервер не успевал обрабатывать информацию, и начал задерживаться ( он просто не успевает так скажем за клиентом)
Поэтому я сделал так, у клиента будет задержка sleep(10) а сервер не будет принимать задежку он постоянно будет слушать!
То есть когда сервер с параметром sleep(10) по общему результату он должен повторить работу клиента, но она накапливается и он дает задержку
Извиняюсь пояснение наверное не очень понятное, просто хотел объяснить примерно с чем связана задержка!
idris070, Некропостинг. А вобще эта проблема отпадает если правильно переписать весь код (Буржуй чёт нахимичил лишнего в коде на видео а остальные неглядя код скатали).
Пример консольного мессенжера. Необходимо скомпилировать два файла .cpp (два приложения) и указать IP-адреса и порты.
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103#include<SFML/Network.hpp>#include<iostream>#include<string>#include<thread>using namespace std;using namespace sf;void Send() //Функция отправитель.{while (true){//Создать соккет отправителя.UdpSocket socket;char message[250]; Packet packet;cin.getline(message, 250); //Передать массив символов. Получатель увидит готовые строки.packet << message;socket.send(packet, "192.168.43.142", 2001);}}void Receive() //Функция получатель{while (true){//Создать соккет получателя и привязать его к своему порту.UdpSocket socket; socket.bind(2002);// Получить от кого-нибудь сообщение.IpAddress sender; unsigned short port; string message; Packet packet;socket.receive(packet, sender, port);packet >> message;cout << message << endl;}}//------- Протокол Udp ----------------+int main(){cout << "Yuriy" << endl; cout << "-----" << endl;thread receive(Receive); thread send(Send); //Вызвать две функции, каждую в отдельном потоке.receive.join(); send.join(); //Ждать окончания работы потоков.size_t z; std::cin >> z; return 0;}/*#include<SFML/Network.hpp>#include<iostream>#include<string>#include<thread>using namespace std;using namespace sf;void Send() //Функция отправитель.{while (true){//Создать соккет отправителя.TcpSocket socket;//Установить связь с получателем.socket.connect("192.168.43.142", 2001);char message[250]; Packet packet;cin.getline(message, 250); //Передать массив символов. Получатель увидит готовые строки.packet << message;socket.send(packet);packet.clear();}}void Receive() //Функция получатель{while (true){//Создать соккет получателя.TcpSocket socket;//Создать соккет слушателя, присвоить ему свой порт и перейти в режим ожидания.TcpListener listener; listener.listen(2002);// Установить связь с абонентом, если он отправил запрос.listener.accept(socket);// Получить сообщение от абонента.string message; Packet packet;socket.receive(packet);packet >> message;cout << message << endl;}}//------- Протокол Tcp ----------------+int main(){cout << "Vladimir Kuznetcov" << endl; cout << "--------------------" << endl;thread receive(Receive); thread send(Send);receive.join(); send.join();size_t z; std::cin >> z; return 0;}*/Внизу, то что за комментировано пример c Tcp-протоколом. Но по мне, так Udp (сверху) работает лучше.
Пользуйтесь на здоровье! )
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.