Сокет TCP в Unix - уведомить сервер, что я сделал отправку - PullRequest
3 голосов
/ 22 июня 2011

У меня есть крошечное маленькое TCP-приложение, где многие клиенты подключаются к серверу, отправляют на него данные (через write () - они также отправляют размер сообщения) и затем завершают работу. У меня есть клиенты отправляют \ 0 \ 0 на сервер при завершении отправки - и я делаю так, чтобы, если сервер получает ноль от read (), то он знал, что что-то пошло не так в клиенте (например, SIGKILL). Мой вопрос - есть ли какой-нибудь программный способ (какой-нибудь вызов sys), чтобы уведомить сервер о том, что я закончил отправку - вместо того, чтобы сервер всегда проверял \ 0 \ 0? Сервер использует poll () для клиентов / прослушивающего сокета, чтобы определить, есть ли что-то для чтения / нового запроса на соединение, кстати.

Должен ли я отправить сигнал? Но как мне узнать, какой дескриптор прекратить опросить тогда?

Я прочитал это но ответы там более или менее, что я использую сейчас

Ответы [ 2 ]

4 голосов
/ 22 июня 2011

Выполнение этого на уровне приложения (например, использование \0\0 в том виде, в котором вы это делаете) - правильный способ сделать это, если ваш протокол немного сложнее, чем модель с одним запросом / ответом.

HTTP 1.0, например, закрывает соединение сразу после одного запроса / ответа: клиент отправляет свою команду запроса, сервер отвечает своим ответом и закрывает соединение.

В протоколах, где имеется более сложный обменСуществуют специальные команды для указания конца сообщения.SMTP и POP3, например, разделены строкой.При отправке содержимого сообщения электронной почты через SMTP вы указываете конец сообщения, используя . в одной строке (. в текущем сообщении экранируется как ..).Вы также получаете команды, такие как QUIT, чтобы указать, что все готово.

В HTTP 1.1 набор заголовков запроса заканчивается пустой строкой (например, GET / HTTP/1.1 + каждый заголовок в строке +пустая строка), поэтому сервер знает, где находится конец запроса.Ответы в HTTP 1.1 затем используют либо заголовок Content-Length (чтобы сигнализировать, когда будет конец тела ответа), либо использовать кодировку chunked Transfer , которая по существу вставляет несколько разделителей, чтобы указать, естьпоступает больше данных (обычно это используется, когда размер данных заранее неизвестен серверу).(Запросы с телом также используют те же заголовки, чтобы указывать, когда запрос заканчивается.)

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

2 голосов
/ 22 июня 2011

Это делается на уровне приложения. В HTTP это делается путем закрытия сокета для ответа. Также в HTTP после того, как сервер получил два возврата, он знает, что запрос GET завершил отправку, затем, если есть заголовок длины содержимого, он знает, что клиент / сервер завершил отправку после X байтов.

Вам нужно будет реализовать нечто подобное.

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