Соединение клиента и сервера на основе sfml
Недавно ради эксперимента сделал две программы - клиент и сервер, грубо говоря. Программы очень простые: клиент выводит несколько кружков на экран, один из которых управляется на клавиши самим пользователем(перемещение в 2D пространстве), и несколько кружков другого цвета - все подключенные к серверу пользователи, кроме нашего. Сервер принимает подключения в отдельном потоке, и в случае наличия подключений, отправляет клиентам данные о всех кружках, кроме их собственного, предварительно получив данные местоположения кружка самого пользователя. Код прилагается:
using namespace std;
using namespace sf;
void thr_serverConnect(bool& metka, string Ip, int port,CircleShape& ball, vector<CircleShape>& vec) {
TcpSocket socket;
while (socket.connect(Ip, port) == Socket::Status::Error) { true; }
int num = 0;
int countOfFalls = 0;
while (metka) {
socket.send(&ball.getPosition(), sizeof(Vector2f)); //Отправляет свои данные -> получает количество клиентов -> получает их данные
size_t received;
socket.receive(&num, sizeof(int), received);
while (num - 1 > vec.size()) { vec.push_back(CircleShape()); int i = vec.size() - 1; vec[i].setFillColor(Color::Blue); vec[i].setRadius(10); }
for (int i = 0; i < num-1; i++) {
Vector2f temp;
socket.receive(&temp, sizeof(Vector2f), received);
vec.at(i).setPosition(temp);
}
if (countOfFalls == 10) { cout << "Server fall connected" << endl; break; }
if (received <= 0) { countOfFalls++; Sleep(100); }
else { countOfFalls = 0; }
}
}
//Серверная часть моего проекта.
void thr1(TcpSocket& socket, vector<CircleShape>& vec, bool& metka,bool& connected) {
bool ready = true;
Vector2f ballclient;
size_t received;
socket.receive(&ballclient, sizeof(Vector2f), received);
CircleShape ballclient2;
ballclient2.setPosition(ballclient);
vec.push_back(ballclient2);
int ID = vec.size() - 1;
int t = vec.size();
int countOfFalls = 0;
socket.send(&t, sizeof(int));
while (metka) {
t = vec.size();
for (int i = 0; i != t; i++) {
if (ID != i) {
socket.send(&vec.at(i).getPosition(), sizeof(Vector2f));
}
}
socket.receive(&ballclient, sizeof(Vector2f), received);
CircleShape ballclient2;
ballclient2.setPosition(ballclient);
vec[ID] = ballclient2;
if (countOfFalls == 10) {
connected = false;
break;
}
if (received <= 0) { countOfFalls++; }
else { countOfFalls = 0; }
Sleep(10);
int t = vec.size();
socket.send(&t, sizeof(int));
}
}
int main() {
setlocale(LC_ALL, "Russian");
vector<CircleShape>csl;
list<bool>metki;
bool ProgramOn = true;
TcpListener listener;
while (true) {
if (listener.listen(15000) == Socket::Status::Done) {
TcpSocket* socket = new TcpSocket;
listener.accept(*socket);
metki.push_back(new bool(true));
//bool& i = ;
cout << "New connect: " << socket->getRemoteAddress() << ":" << socket->getRemotePort() << endl;
cout << "Now we have " << metki.size() << " connections" << endl;
thread NetConnect(thr1, ref(*socket), ref(csl), ref(ProgramOn), ref(*metki.end()));
NetConnect.detach();
};
}
ProgramOn = false;
return 0;
}
Первая функция запускается в клиенте в отдельном потоке и служит для соединения и отправки/получения данных сервера. Функция перемещения(main-функция) клиента тут не присутсвует, так как в ней нет ничего, связанного с сетью. Просто изменение позиции ball-а, который передается в поток.
Итак, суть проблемы: Программа полностью работает на ip адресах типа 127.0.0.1 и моем локальном ip-адресе(адресер в закрытой сети роутера, где присутсвуют все устройства, подлюченные к нему), также работает на виртуальной машине-моим пк, если использовать локальный ip, также работает между моим пк-пк, находящемся в этой же локальной сети, если использовать локальный ip. Есть еще сеть, созданная Hamachi на перманентной основе - она тоже подходит для подключения, но только на моем пк(это так, к слову). Проблема в том, что между моим пк и пк, находящемся в другой сети, образно, подключенным к другому роутеру, связь настроить не получается. Просто бесконечное ожидание, даже попытки подключиться не происходит. Если что, то порт на моем пк(всегда сервер запускался именно у меня) открыт на входящие соединения. На счет портов внелокльного пк - ничего не могу сказать. Я недостаточно хорошо знаю устройство tcp сетей, а потому не могу выявить ошибку сам, пробовал изучать некоторую литературу, но ничего не смог для себя выделить. В Интернете тоже искал, но ничего конкретного сказано не было. Я не пробовал подключать внелокальный пк через Hamach-евский ip и не уверен, сработает это или нет. Я не знаю, должен ли создавать разрешения доступа к портам моего приложения на внелокальном пк. Подскажите, пожалуйста, что именно я сделал не так.
Буду благодарен за любую помощь :)
Ответы (1 шт):
С проблемой получилось справиться и вот как. На роутере сделана переадресация для указанного в подключении порта(у меня 15000) на мой локальный адрес(локальный адрес моего пк в локальной сети роутера). Ссылка, о том, как это сделать(большое спасибо @AlexGlebe): http://hamachi-pc.ru/instructions/kak-otkryt-porty-cherez-khamachi.html
Порты на пк клиента не были открыты, но это не потребовалось. А вот порт, используемый для подключения ко мне(15000 - в моем случае) открыт для внешний/внутренних подключений через брандмауэр Windows, если что, в ссылке есть информация о том, как это сделать через Hamachi. Спасибо всем, кто пытался помочь :)