сервер - связь с клиентом - PullRequest
1 голос
/ 31 мая 2011

Я пишу сетевую программу C, в которой клиент отправляет блок данных на сервер, и я хочу убедиться, что все данные были прочитаны сервером, прежде чем я закрою сокет со стороны клиента.Я думал об отправке специального символа 'ok' обратно с сервера клиенту, но я думаю, что если во время выполнения серверной программы что-то не так, и сервер закрывает канал с его стороны (например, сбой чтения системного вызова)клиент будет ждать системного вызова read для чего-то, что никогда не придет.Любая идея о том, как я могу решить это?

спасибо, Никос

Ответы [ 6 ]

1 голос
/ 31 мая 2011

Я хочу убедиться, что все данные были прочитаны сервером b * прежде чем я закрою сокет со стороны клиента *.

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

.send / write данные, они ушли из ваших рук.Он скопирован в буфер ядра и отправлен через некоторое время.За кулисами (где-то глубоко в netinet) соединение не закрывается, пока все отправленные данные не будут подтверждены / соединение прервано по другим причинам.

0 голосов
/ 31 мая 2011

Кажется, что для вашего клиента есть четыре возможных результата:

  1. Сервер выполняет команду и отправляет обратно «OK».
  2. Сервер не может выполнить команду и вместо этого отправляет строку ошибки.
  3. Сервер завершает работу, аварийно завершает работу или иным образом отключается при попытке выполнить команду, и соединение TCP закрывается.
  4. Сервер глючит и зависает при попытке выполнить команду, или по какой-то другой причине он никогда не отправляет ответ (но поддерживает соединение TCP открытым).

Первыйтри могут быть обработаны в прямой форме на клиенте.Чтобы справиться с четвертым, вам нужно реализовать тайм-аут на стороне клиента - но тогда вы рискуете преждевременно отключиться, когда на самом деле сервер просто не отвечает, а не прерывается.Вероятно, лучше всего сделать тайм-аут довольно щедрым (например, 30 секунд?), А также убедиться, что ваш сервер надежен и не зависает.:)

0 голосов
/ 31 мая 2011

Нет необходимости беспокоиться о том, когда закрывать сокет на стороне вашего клиента. Пока данные записаны в сокет, вы можете закрыть их в любое время после этого. @cnicutar хорошо объясняет это в своем ответе.

Что касается специальных символов подтверждения от вашего сервера обратно к клиенту, вам не нужно беспокоиться об этом с TCP. Тем не менее, вы можете изменить свой блок данных так, чтобы он включал заголовок, указывающий, сколько данных есть. Например, первые 4 байта блока данных могут быть полем длины, указывающим, сколько еще байтов существует. Сервер может прочитать первые 4 байта, а затем узнать, сколько еще байтов нужно прочитать. TCP-коммуникации обычно имеют что-то вроде этого.

0 голосов
/ 31 мая 2011

протокол чередующихся битов - способ решить эту проблему.Существуют различные способы реализации этого.

Когда A отправляет сообщение, оно повторно отправляет его непрерывно с тем же порядковым номером, пока не получит подтверждение от B, которое содержит тот же порядковый номер.Когда это происходит, А дополняет (переворачивает) порядковый номер и начинает передавать следующее сообщение.

0 голосов
/ 31 мая 2011

Реализация тайм-аута в клиенте.Подождите некоторое настраиваемое / разумное количество времени на ответ от сервера.Если этот период времени истек, действуйте соответственно.

0 голосов
/ 31 мая 2011

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

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