Как установить TCP-соединение между двумя серверами, если оба могут установить соединение? - PullRequest
3 голосов
/ 17 марта 2010

У меня есть определенное количество серверов, которые могут локально обрабатывать данные по-своему. Но через некоторое время я хочу синхронизировать некоторые состояния, которые являются общими для каждого сервера. Моя идея заключалась в том, чтобы установить соединение TCP от каждого сервера к другим серверам, как ячеистая сеть.

Моя проблема заключается в том, что в каком порядке я устанавливаю соединения, поскольку здесь нет «главного» сервера, так что каждый сервер отвечает за создание там собственных соединений с каждым сервером.

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

Но как мне справиться с тем фактом, что 2 сервера пытаются подключиться одновременно? Потому что тогда я получаю 2 TCP-соединения вместо 1.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 17 марта 2010

При подключении к серверу вам потребуется протокол квитирования, чтобы вы могли проверить, можно ли начинать отправку / получение данных, в противном случае вы можете подключиться к одной из конечных точек и начать отправку данных только немедленно. чтобы другой конец разорвал соединение.

Чтобы убедиться, что к серверу подключено только одно соединение, вам просто нужно что-то вроде этого псевдокода:

remote_server = accept_connection()
lock mutex;
if(already_connected(remote_server)) {
  drop_connection(remote_server)
}
unlock mutex;

Если ваш сервер не многопоточный, вам не нужны блокировки для защиты, когда вы проверяете, подключены ли вы уже - поскольку не будет никаких проблем "в то же время".

Вам также потребуется механизм повторных попыток подключения к серверу на основе небольшого случайного льготного периода в случае, если удаленный сервер закрыл только что установленное соединение.

Если соединение было закрыто, подождите немного, проверьте, подключено ли уже (возможно, другой конец установил вам соединение в это время) и попробуйте подключиться снова. Это сделано для того, чтобы избежать ситуации, когда оба конца устанавливают соединение одновременно, но другой конец закрывает его из-за вышеуказанной логики.

1 голос
/ 17 марта 2010

Просто как идея. Каждый сервер принимает соединение, а затем обнаруживает, что у него есть два TCP-соединения между одними и теми же серверами. Затем одно соединение выбирается для закрытия. Способ выбора того, какое соединение нужно закрыть, нужно просто реализовать. Например, оба сервера должны сравнить свои имена (или их IP-адрес, или их UID), и соединение, инициированное сервером, чье имя меньше (или UID), должно быть закрыто.

0 голосов
/ 17 марта 2010

Хотя лучшее решение подразумевает создание отдельного «LoadBalancer», к которому подключены все ваши серверы, это небольшое предложение, чтобы убедиться, что соединения не создаются одновременно.

Ваши серверы могут устанавливать соединения в разное время, используя

bool CreateConnection = (time ()% i == 0)

if (CreateConnection) {...}

где i - идентификатор конкретного сервера. время () может быть в секундах или долях секунды, в зависимости от ваших требований.

Это гарантирует, что вы никогда не получите два сервера, соединяющихся одновременно друг с другом. Если у вас нет идентификаторов для серверов, вы можете использовать случайное значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...