2014-12-17 4 views
2

Я работаю над проектом, который является сервер-клиентским приложением на основе WinSock на C++. Я сделал все необходимое для связи между сервером и клиентом, с которым я могу отправлять и получать сообщения между ними.Клиентский обмен сообщениями в программировании сокетов

Теперь мне нужно знать, как выполнить клиентскую часть обмена сообщениями и как должна быть выполнена работа. Я знаю только, что, например, если клиент A и Клиент B должны связываться друг с другом, клиент A должен отправить сообщение на сервер, сервер получит сообщение и отправит его клиенту B.

Если это необходимо пожалуйста, помогите мне узнать, как сервер должен знать что-либо о получателе (который в данном случае является клиентом B)?

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

Любая помощь приветствуется.

+1

То, как я это делал, было то, что каждый раз, когда клиент подключается к серверу, я предоставляю этому клиенту уникальный идентификатор. Всякий раз, когда другой клиент хочет отправить сообщение, он отправляет уникальный идентификатор получателя и сообщение. Сервер отправляет это сообщение клиенту с идентификатором, для которого предназначено сообщение. У меня была функция для «опроса» сервера для клиентов. Каждый раз, когда клиент подключался к серверу, я посылал команду каждому клиенту для обновления своего онлайн-списка. Когда клиент отключается, он отправляет команду каждому клиенту для обновления своего списка .. в основном, как msn-messenger. – Brandon

+0

Это интересное решение. Но когда вы говорите: «Всякий раз, когда другой клиент хочет отправить сообщение, он отправляет уникальный идентификатор получателя и сообщение». Вы имеете в виду, что он отправляет два разных сообщения один для уникального идентификатора получателя, а другой для сообщения, или сообщение должно иметь оба информацию и каков формат сообщения? – user3530012

+1

Я сделал свой собственный формат. Он прошел следующим образом: struct CMsg {unsigned long ID, Length, Command; char * Message;}; Я написал структуру в массив байтов и отправил ее на сервер. Сервер считывает идентификатор (sizeof (unsigned long)), затем длину, затем команду. Наконец, он читает количество символов «Длина» (сообщение). – Brandon

ответ

2
  1. Клиент A беседует с сервером.
  2. Клиент B беседует с сервером.
  3. Сервер определяет A необходимо поговорить непосредственно с B и наоборот.
  4. Сервер отправляет A и B сообщение, содержащее сведения о том, как разговаривать друг с другом (IP-адрес, порты и т. Д.). Сообщение также содержит сведения, которые (A или B) будут инициировать контакт, тайм-ауты и т. Д.
  5. После получения, каждый A и B начинает прослушивать порты, детализированные сервером.
  6. Тот, кто был настроен в сообщении, чтобы начать контакт, делает это (переговоры с B или наоборот).

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

+0

Не могли бы вы помочь мне с [этим] (http://stackoverflow.com/q/38733264/6027611) –

5

Один из способов добиться этого - иметь одного из клиентов для работы в качестве сервера после некоторого общения через фактический сервер. Вам нужно создать свой протокол. С учетом этого:

1- Клиент A: -Hey, Server !. Сообщите клиенту B создать комм-сервер, чтобы я мог напрямую связаться с ним.

2- Сервер: -Хей, Клиент Б !. Запустите экземпляр сервера и скажите мне свойства соединения, чтобы я мог передать его клиенту A, чтобы он мог подключиться к вам.

3- Клиент B: -Хей, Сервер !. Я готов принять запрос на подключение для клиента A. Вот мои свойства подключения ...

4-Сервер: -Client A !! Здесь свойства присоединительные клиента B. Возьмите его или оставить его ... Я сделал ..

5 Клиент A:? -Эй, сервер B .. Могу ли я подключить ..

Это это протокол. Поэтому любой клиент сначала инициирует запрос на сервер, который включает в себя тип сообщения «Я, запрашивающий подключение к клиенту x ..». Сервер управляет клиентом x, ответами клиента x, сервером ретранслирует ответ клиенту инициатора ... А также вы должны внедрить обработчики ошибок, политики отказа или некоторые другие вещи, о которых вы можете думать, чтобы управлять всем протоколом.

+1

Если ни один из клиентов не может запустить сервер (выталкивая дыру в любом брандмауэре, за которым они находятся), тогда это может быть невозможно клиент маршрутных сообщений клиенту. В этом случае есть некоторые грязные трюки, которые вы можете попробовать (отправьте UDP-пакеты с обоих концов и посмотрите, сможете ли вы получить «ответы»), но нет действительно гарантированного решения. – Speed8ump

+0

@ Speed8ump UDP-пакеты - это зло! :)) Клиент B может сказать «сервер, я не могу создать комм-сервер» на этапе 3 выше, и сервер может передать «клиент a, клиент b не подлежит вам» .. на этапе 4. Или, если клиент b может запустить сервер, но если есть брандмауэр, сервер может проверить соединение. свойства b после этапа 3, и вместо того, чтобы сказать «здесь реквизит» на этапе 4, он может сказать, что «клиент б встал, но не подключается» к клиенту а .. И да, нет гарантированного решения. Вот почему протокол должен управляться очень хорошо .. –

1

Подумайте о связи клиент-сервер как о старой радиосвязи.

  1. А требуется поговорить с B, поэтому B должен слушать
  2. заканчивает свою речь (вы просто отправить ключевое слово, что-то вроде «// EOC», или использовать фиксированную ширину для сообщений).
  3. B должен говорить с А, следовательно, А не должен говорить, чтобы позволить B поговорить с

итерации до команды конца-связи

так просто представьте, что речь идет write, и слушать это read

B: read -> A: write 
A: read -> B: write 

забудьте использовать ключевое слово, чтобы разъединить 2 клиентов, или вы могли бы иметь некоторое плохое поведение из системных вызовов

Смежные вопросы