Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Определение доступности UDP сервера

26K
13 декабря 2009 года
CyBOSSeR
32 / / 07.05.2008
Здравствуйте, уважаемые форумчане.
Занимаюсь разработкой многопользовательского редактора топологии ЛВС, использующего протокол UDP и асинхронные сокеты.
Один из компьютеров выступает в роли сервера, к которому подключаются клиенты.
В случае падения сервера, один из клиентов должен принять эстафету от сервера и стать сервером.
Проблема в том как определить сам факт того, что сервер упал (например из-за падения сети).
Каким образом можно определить, доступен сервер или нет?

sendto никогда не возвращает SOCKET_ERROR, даже если сообщение посылается на совершенно левый адрес.
26K
14 декабря 2009 года
CyBOSSeR
32 / / 07.05.2008
Кто нибудь может помочь советом?
2
14 декабря 2009 года
squirL
5.6K / / 13.08.2003
Цитата: CyBOSSeR

В случае падения сервера, один из клиентов должен принять эстафету от сервера и стать сервером.
Проблема в том как определить сам факт того, что сервер упал (например из-за падения сети).


ваша задача напоминает мне механизм определения Master Browser в сетях Microsoft.
используйте переодические броадкасты с клиентов, для определения текущего главного сервера. по алгоритму:

1. всем чмоке, а кто сейчас сервер?
2. получен ответ - заканчиваем работу алгоритма, сервер известен.
3. ответа нет - инициируем выборы нового сервера
4. выборы по определенному алгоритму прошли - определен новый главный сервер - через некоторое время переходим к пункту 1.

ну и тут следует учесть ньюансы. например - инициализации выборов сервера, при обнаружении падения сервера, при попытке с ним пообщаться, а не во время броадкаста.

26K
14 декабря 2009 года
CyBOSSeR
32 / / 07.05.2008
Идея интересная.

Изначально предполагал следующее решение данной проблемы.

Сервер постоянно отсылает широковещательные сообщения со своим именем.

Каждому клиенту при подключении к серверу выдается целочисленный идентификатор.

На каждое сообщение клиента сервер должен прислать сообщение подтверждение, если подтверждение не пришло - сервер упал. Клиент засыпает на количество секунд равное идентификатор_клиента * некая_константа, после пробуждения проверяет передает ли кто-нибудь широковещательные сообщения с именем только-что упавшего сервера. Если да - подключаемся, нет - запускаемся в режиме сервера, и начинаем вещать имя упавшего сервера.

Но вот с подтверждениями проблема.

Пользователь на клиентской машине передвинул элемент, мы отсылаем сообщение о произошедшем серверу, и должны принять подтверждение. Проблема в том, что к этому времени на сокете может быть n-ое количество сообщений от сервера, и как мне оттуда вытащить подтверждение?
376
14 декабря 2009 года
Absolut
220 / / 22.11.2002
Для проверки доступности UDP-сервера как вариант можно использовать connect для UDP сокетов. В таком случае нужно будет пользоваться функциями send и recv (вместо send_to, recv_from), но параллельно по ICMP должен приходить ответ о доступности или не доступности сервера. О доступности можно будет судить по возвращаемому значению send. Как-то так.
26K
14 декабря 2009 года
CyBOSSeR
32 / / 07.05.2008
Цитата: Absolut
Для проверки доступности UDP-сервера как вариант можно использовать connect для UDP сокетов. В таком случае нужно будет пользоваться функциями send и recv (вместо send_to, recv_from), но параллельно по ICMP должен приходить ответ о доступности или не доступности сервера. О доступности можно будет судить по возвращаемому значению send. Как-то так.


Ты уверен что этот вариант сработает?
Но тогда вопрос, как и буду различать на сервере с какого адреса пришли датаграммы?

26K
14 декабря 2009 года
CyBOSSeR
32 / / 07.05.2008
Код:
#include <iostream>
#include <WinSock2.h>
#include <winbase.h>

int main()
{
  WSAData wsd;

  if(WSAStartup(MAKEWORD(2, 2), &wsd) == SOCKET_ERROR){
    std::cout << "WSAStartup call failed. WSAError" << WSAGetLastError() << std::endl;
    return 0;
  }

  SOCKET s;

  if((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET){
    std::cout << "socket call failed. WSAError" << WSAGetLastError() << std::endl;
    return 0;
  }

  sockaddr_in server;

  server.sin_family = AF_INET;
  server.sin_port = htons(35000);
  server.sin_addr.s_addr = inet_addr("100.100.100.1");

  if(connect(s, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR){
    std::cout << "connect call failed. WSAError" << WSAGetLastError() << std::endl;
    return 0;
  }

  char data[] = "Test";

  while(send(s, data, strlen(data) + 1, 0) != SOCKET_ERROR)
    std::cout << "send call successful" << std::endl;

  return 0;
};

Опять же никаких ошибок:(.
376
15 декабря 2009 года
Absolut
220 / / 22.11.2002
Похоже под Win это не работает. В таком случае, можно самому параллельно пинговать сервер на предмет доступности.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог