В Delphi до 7-й версии включительно модуль WinSock содержит ошибку — параметры LocalSockaddr
RemoteSockaddr
функции GetAcceptExSockAddrs
имеют в нем тип TSockAddr
вместо PSockAddr
. Из-за этой ошибки функцию GetAcceptExSockAddrs
в этих версиях Delphi необходимо самостоятельно импортировать. Следует заметить, что во многих модулях для WinSock 2 от независимых разработчиков объявление этой функции скопировано из стандартного модуля вместе с ошибкой.Первые четыре параметра функции GetAcceptExSockAddrs
AcceptEx
оказались данные от клиента и адреса, и размеры частей буфера, зарезервированных для данных и для адресов. Значения этих параметров должны совпадать со значениями аналогичных параметров в соответствующем вызове AcceptEx
. Через параметр LocalSockaddrs
возвращается указатель на то место в буфере, в котором хранится адрес привязки сокета sAcceptSocket
, а через параметр LocalSockaddrsLength
— длина адреса (16 в случае TCP). Адрес клиента и его длина возвращаются через параметры RemoteSockaddrs
и RemoteSockaddrsLength
. Следует особенно подчеркнуть, что указатели LocalSockaddrs
и RemoteSockaddrs
указывают именно на соответствующие части буфера: память для них специально не выделяется и, следовательно, не должна освобождаться, а свою актуальность они теряют при освобождении буфера.Последняя из дополнительных функций, TransmitFile
TransmitFile
function TransmitFile(hSocket: TSocket; hFile: THandle; nNumberOfBytesToWrite, nNumberOfBytesPerSend: DWORD; lpOverlapped: POverlapped; lpTransmitBuffers: PTransmitFileBuffers; dwReserved: DWORD): BOOL;
Функция TransmitFile
hSocket
, файл — параметром hFile
. Дескриптор файла обычно получается с помощью функции стандартного API CreateFile
. Файл рекомендуется открывать с флагом FILE_FLAG_SEQUENTIAL_SCAN
, т.к. это повышает производительность.Параметр nNumberOfBytesToWrite
Функция TransmitFile
nNumberOfBytesPerSend
определяет размер одной порции данных. Он может быть равен нулю — в этом случае система сама определяет размер порции. Этот параметр критичен только в случае дейтаграммных протоколов, потому что при этом размер порции определяет размер дейтаграммы. Для TCP данные, хранящиеся в буфере, передаются в сеть целиком или по частям в зависимости от загрузки сети, готовности принимающей стороны и т.п., а какими порциями они попали в буфер, на размер пакета почти не влияет. Поэтому для TCP-сокета параметр nNumberOfBytesPerSend
лучше установить равным нулю.Параметр lpOverlapped
TOverlapped
, использующуюся для перекрытого ввода-вывода. Эту структуру мы обсуждали при описании функции AcceptEx
. В отличие от AcceptEx
, в TransmitFile
этот параметр добыть равным nil
, и тогда операция передачи файла не будет перекрытой.Если параметр lpOverlapped
nil
, передача файла начинается с той позиции, на которую указывает файловый указатель (для только что открытого файла этот указатель указывает на его начало, а переместить его можно, например, с помощью функции SetFilePointer
; также он перемещается при чтении файла с помощью ReadFile
). Если же параметр lpOverlapped
задан, то передача файла начинается с позиции, заданной значениями полей Offset
и OffsetHigh
, которые должны содержать соответственно младшую и старшую часть 64-битного смещения стартовой позиции от начала файла.