Читаем О чём не пишут в книгах по Delphi полностью

Первый параметр данной функции задаёт сокет, который служит для передачи данных. Здесь нужно указать значение, полученное ранее от функции socket. Параметр Buf задаёт буфер, в котором хранятся данные для отправки, а параметр len — размер этих данных в байтах. Параметр flags позволяет указать некоторые дополнительные опции, которых мы здесь касаться не будем, т. к. в большинстве случаев они не нужны. Пока следует запомнить, что параметр flags в функции sendto, а также в других функциях, где он встречается, должен быть равен нулю. Параметр addrto задает адрес (состоящий из IP-адреса и порта) удаленного сокета, который должен получить эти данные. Значение параметра addrto должно формироваться по тем же правилам, что значение аналогичного параметра функции bind, за исключением того, что IP-адрес и порт должны быть заданы явно (т. е. не допускаются значения INADDR_ANY и нулевой номера порта). Параметр tolen задает длину буфера, отведенного для адреса, и должен быть равен SizeOf(TSockAddr). Один вызов функции sendto приводит к отправке одной дейтаграммы. Данные, переданные в sendto, никогда не разбиваются на несколько дейтаграмм, и данные, переданные последовательными вызовами sendto, никогда не объединяются в одну дейтаграмму.

Функцию sendto можно использовать с сокетами, не привязанными к адресу. В этом случае внутри библиотеки сокетов будет неявно вызвана функция bind для привязки сокета к адресу INADDR_ANY и нулевому порту (т. е. адрес и порт будут выбраны системой).

Если выходной буфер сокета имеет ненулевой размер, sendto помещает данные в этот буфер и сразу возвращает управление программе, а собственно отправка данных осуществляется библиотекой сокетов в фоновом режиме. Поэтому успешное завершение sendto гарантирует только то, что данные скопированы в буфер и что на момент их копирования не обнаружено никаких проблем, которые делали бы невозможной их отправку. Но такие проблемы могут возникнуть позже, поэтому даже в случае успешного завершения sendto отправитель не получает гарантии, что данные посланы. Если в выходном буфере сокета не хватает места для новой порции данных, sendto не возвращает управление программе (т. е. блокирует ее) до тех пор, пока в буфере за счет фоновой отправки не появится достаточно места или не будет обнаружена ошибка.

Если размер выходного буфера сокета равен нулю, функция sendto копирует данные сразу в сеть, без промежуточной буферизации. Когда функция вернет управление программе, программа может быть уверена, что информация уже успешно передана в сеть. Однако даже в этом случае успешное завершение sendto не гарантирует доставку информации: дейтаграмма может потеряться по дороге.

В случае успешного завершения функция sendto возвращает количество байтов, скопированных в буфер (или переданных напрямую в сеть, если буфера нет). Для протокола UDP это значение может быть равно только значению параметра len, хотя для некоторых других протоколов (например, TCP) возможны ситуации, когда в буфер сокета копируется только часть данных, переданных программой, и тогда sendto возвращает значение в диапазоне от 1 до len. Если при выполнении sendto возникает ошибка, она возвращает значение SOCKET_ERROR (эта константа имеет отрицательное значение).

Для получения данных, присланных сокету, предназначена функция recvfrom, имеющая следующий прототип:

function recvfrom(s: TSocket; var Buf; len, flags: Integer; var from: TSockAddr; var fromlen: Integer): Integer;

Параметр s задает сокет, из входного буфера которого будут извлекаться данные, Buf — буфер, в который эти данные будут копироваться, а len — размер этого буфера. Параметр flags задает дополнительные опции и в большинстве случаев должен быть равен нулю. Параметр from выходной: в него помещается адрес, с которого была послана дейтаграмма. Параметр fromlen задает размер в байтах буфера для адреса отправителя. При вызове функции значение переменной, подставляемой в качестве фактического параметра, должно быть равно SizeOf(TSockAddr). Функция меняет это значение на ту длину, которая реально потребовалась для хранения адреса отправителя (в случае UDP это значение также будет равно SizeOf(TSockAddr).

В оригинале параметры from и fromlen передаются как указатели, и программа может использовать вместо них нулевые указатели, если ее не интересует адрес отправителя. Разработчики модуля WinSock заменили указатели параметрами-переменными, что в большинстве случаев удобнее. Но для передачи нулевых указателей приходится в качестве фактических параметров подставлять неуклюжие конструкции PSockAddr(nil)^ и PInteger(nil)^.

Перейти на страницу:

Похожие книги

1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных