Передача данных

Передача данных


В сетевом программировании самое главное — уметь отправлять и принимать данные. Для пересылки данных по сокету употребляются функции send и WSASend. Аналогично, для приема данных есть функции recv и WSARecv.

Все буферы, применяемые при отправке и приеме данных, состоят из частей типа char. To есть эти функции не созданы для работы с шифровкой UNICODE. Это в особенности принципиально для Windows СЕ, потому что она употребляет UNICODE по дефлоту. Выслать строчку знаков UNICODE можно 2-мя методами: в начальном виде либо привести к типу char. Аспект в том, что при указании количества отправляемых либо принимаемых знаков итог функции, определяющей длину строчки, необходимо помножить на 2, потому что каждый UNICODE-символ занимает 2 б строкового массива. Другой метод: поначалу перевести строчку из UNICODE в ASCII функцией WideCharToMultiByte.

Все функции приема и отправки данных при появлении ошибки возвращают код SOCKET_ERROR. Для получения более подробной инфы об ошибке можно вызвать функцию WSAGetLastError. Самые всераспространенные ошибки — WSAECONNABORTED и WSAECONNRESET. Обе появляются при закрытии соединения: или по истечении времени ожидания, или при закрытии соединения партнерским узлом. Еще одна обычная ошибка — WSAEWOULDBLOCK, обычно происходит при использовании неблокирующих либо асинхронных сокетов. По существу, она значит, что функция не может быть выполнена на этот момент. В следующейглаве будут описаны различные способы ввода-вывода Winsock, которые посодействуют избежать этих ошибок.

^ Функции send и WSASend

API-функция send для отправки данных по сокету определена так:

// Code 3.13

int send(

SOCKET s,

const char FAR * buf,

int len,

int flags

);

Параметр s определяет сокет для отправки данных. 2-ой параметр — buf, показывает на символьный буфер, содержащий данные для отправки. 3-ий — len, задает число отправляемых из буфера знаков. И последний параметр — flags, может принимать значения 0, MSG_DONTROUTE, MSG_OOB, либо итог логического Либо над хоть какими из этих характеристик. При указании флага MSG_DONTROUTE транспорт не будет маршрутизировать отправляемые пакеты. Обработка этого запроса остается на усмотрение базисного протокола (к примеру, если транспорт не поддерживает этот параметр, запрос игнорируется). Флаг MSG_OOB показывает, что данные должны быть высланы вне полосы (out of band), другими словами срочно.

При успешном выполнении функция send возвратит количество переданных б, по другому — ошибку SOCKET_ERROR. Одна из обычных ошибок — WSAECONNABORTED, происходит при разрыве виртуального соединения из-за ошибки протокола либо истечения времени ожидания. В данном случае сокет должен быть закрыт, потому что он больше не может употребляться. Ошибка WSAECONNRESET происходит, если приложение на удаленном узле, выполнив аппаратное закрытие, сбрасывает виртуальное соединение, либо внезапно заканчивается, либо происходит перезагрузка удаленного узла. В этой ситуации сокет также должен быть закрыт. Еще одна ошибка — WSAETIMEDOUT, нередко происходит при обрыве соединения из-за сбоев сети либо отказа удаленной системы без предупреждения.



Функция Winsock версии 2 WSASend — аналог send, определена так:

// Code 3.14

int WSASend(

SOCKET s,

LPWSABUF lpBuffers,

DWORD dwBufferCount,

LPDWORD lpNumberOfBytesSent,

DWORD dwFlags,

LPWSAOVERLAPPED lpOverlapped,

LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE

);

Сокет является реальным описателем сеанса соединения. 2-ой параметр показывает на структуру WSABUF либо на массив этих структур. 3-ий — определяет число передаваемых структур WSABUF. Структура WSABUF включает сам символьный буфер и его длину. Может появиться вопрос: для чего необходимо отправлять более 1-го буфера за один раз? Это именуется всеохватывающим вводом-выводом (scatter-gather I/O). Подробней он будет дискуссироваться дальше, на данный момент можно отметить, что при использовании нескольких буферов для отправки данных по сокету соединения массив буферов отчаливает, начиная с первой и заканчивая последней структурой WSABUF.

Параметр lpNumberOfBytesSent — указатель на тип DWORD, который после вызова WSASend содержит общее число переданных б. Параметр флагов dwFlags таковой же, что и в функции send. Последние два указателя — 1рOverlapped и lpCompletionROUTINE употребляются для перекрытого ввода-вывода (overlapped I/O) — одной из моделей асинхронного ввода-вывода, поддерживаемых Winsock (см. также последующую главу).

WSASend присваивает параметру lpNumberOfBytesSent количество записанных б. При успешном выполнении функция возвращает 0, по другому — SOCKET_ERROR. Ошибки те же, что и у функции send.

^ Функция WSASendDisconnect

Это спец функция употребляется изредка. Она определена так:

// Code 3.15

int WSASendDisconnect (

SOCKET s,

LPWSABUF lpOUT boundDisconnectData

)

^ Срочные данные

Если приложению требуется выслать через потоковый сокет информацию более высочайшего приоритета, оно может обозначить эти сведения как срочные данные (out-of-band, OOB). Приложение с другой стороны соединения получает и обрабатывает ООВ-данные через отдельный логический канал, концептуально независящий от потока данных.

В TCP передача ООВ-данных реализована методом прибавления 1-битового маркера (именуемого URG) и 16-битного указателя в заголовке сектора TCP, которые позволяют выделить принципиальные байты в главном трафике. Сейчас для TCP есть два метода выделения срочных данных. В RFC 793, описывающем TCP и концепцию срочных данных, говорится, что указатель срочности в заголовке TCP является положительным смещением б, последующего за б срочных данных. Но в RFC 1122 это смещение трактуется, как указатель на сам б срочности.

В спецификации Winsock под термином ООВ понимают как независящие от протокола ООВ-данные, так и реализацию механизма передачи срочных данных в TCP. Для проверки, есть ли в очереди срочные данные, вызывается функция ioctlsocket с параметром SIOCATMARK. Подробнее об этой функции — в следующих главах.

В Winsock предвидено несколько методов передачи срочных данных. Можно встроить их в обыденный поток, или, отключив эту возможность, вызвать отдельную функцию, возвращающую только срочные данные. Параметр SO_OOBINLINE управляет поведением ООВ-данных (он тщательно дискуссируется в следующих главах).

В ряде всевозможных случаев срочные данные употребляют программки Telnet и Rlogin. Если не планируется писать собственные версии этих программ, следует избегать внедрения срочных данных — они не стандартизированы и могут иметь другие реализации на хороших от Win32 платформах. Если необходимо временами передавать срочно какую-то информацию, можно сделать отдельный управляющий сокет для срочных данных, а основное соединение предоставить для обыкновенной передачи данных.

Функция WSASendDisconnect начинает процесс закрытия сокета и посылает надлежащие данные. Она доступна только для протоколов, поддерживающих постепенное закрытие и передачу данных при его осуществлении. Ни один из имеющихся поставщиков транспорта сейчас не поддерживает передачу данных о закрытии соединения. Функция WSASendDisconnect действует аналогично shutdown с параметром SD_SEND, но также посылает данные, находящиеся в параметре boundDisconnectData. После ее вызова отправлять данные через сокет нереально. В случае плохого окончания WSASendDisconnect возвращает значение SOCKET_ERROR. Ошибки, встречающиеся при работе функции, подобны ошибкам send.


Загрузка...

^ Функции recv и WSARecv

Функция recv — основной инструмент приема данных по сокету. Она определена так:

// Code 3.16

int recv(

SOCKET s,

char FAR * buf,

int len,

int flags

);

Параметр s определяет сокет для приема данных. 2-ой параметр — buf, является символьным буфером и предназначен для приобретенных данных, a len показывает число принимаемых б либо размер буфера buf. Последний параметр — flags, может принимать значения 0, MSG_PEEK, MSG_OOB либо итог логического Либо над хоть какими из этих характеристик. Очевидно, 0 значит отсутствие особенных действий. Флаг MSG_PEEK показывает, что доступные данные должны копироваться в принимающий буфер и при всем этом оставаться в системном буфере. По окончании функция также возвращает количество ожидающих б.

Считывать сообщения таким макаром не рекомендуется. Не много того, что из-за 2-ух системных вызовов (1-го — для считывания данных, и другого, без флага MSG_PEEK — для удаления данных), понижается производительность. В ряде всевозможных случаев этот метод просто не надежен. Объем возвращаемых данных может не соответствовать их суммарному доступному количеству. К тому же, сохраняя данные в системных буферах, система оставляет меньше памяти для размещения входящих данных. В итоге миниатюризируется размер окна TCP для всех отправителей, что не позволяет приложению достигнуть наибольшей производительности. Идеальнее всего скопировать все данные в свой буфер и обрабатывать их там. Флаг MSG_OOB уже дискуссировался ранее при рассмотрении отправки данных.

Внедрение recv в сокетах, нацеленных на передачу сообщений либо дейтаграмм, имеет несколько особенностей. Если при вызове recv размер ожидающих обработки данных больше предоставляемого буфера, то после его полного наполнения появляется ошибка WSAEMSGSIZE. Ошибка превышения размера сообщения происходит только при использовании протоколов, нацеленных на передачу сообщений. Потоковые протоколы буферизируют поступающие данные и при запросе приложением предоставляют их в полном объеме, даже если количество ожидающих обработки данных больше размера буфера. Таким макаром, ошибка WSAEMSGSIZE не может произойти при работе с потоковыми протоколами.

Функция WSARecv обладает дополнительными по сопоставлению с recv способностями: поддерживает перекрытый ввод-вывод и фрагментарные дейтаграммные извещения.

// Code 3.17

int WSARecv(

SOCKET s,

LPWSABUF lpBuffers,

DWORD dwBufferCount,

LPOWORD lpNumberOfBytesRecvd,

LPDWORD lpFlags,

LPWSAOVERLAPPED lpOveflapped,

LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE

);

Параметр s — сокет соединения. 2-ой и 3-ий характеристики определяют буферы для приема данных. Указатель lpBuffers ссылается на массив структур WSABUF, a dwBufferCount — определяет количество таких структур в массиве. Параметр lpNumberOfBytesReceived в случае незамедлительного окончания операции получения данных показывает на количество принятых этим вызовом б. Параметр lpFlags может принимать значения MSG_PEEK, MSG_OOB, MSG_PARTIAL либо итог логического Либо над хоть какими из этих характеристик.

У флага MSG_PARTIAL зависимо от метода использования могут быть различные значения и смысл. Для протоколов, нацеленных на передачу сообщений, этот флаг задается после вызова WSARecv (если все сообщение не может быть возвращено из-за нехватки места в буфере). В данном случае каждый следующий вызов WSARecv задает флаг MSG_PARTIAL, пока сообщение не будет прочитано полностью. Если этот флаг передается как входной параметр, операция приема данных должна закончиться, как данные будут доступны, даже если это только часть сообщения. Флаг MSG_PARTIAL употребляется только с протоколами, нацеленными на передачу сообщений. Запись каждого протокола в каталоге Winsock содержит флаг, указывающий на поддержку этой способности (см. также следующие главы). Характеристики lpOverlapped и lpCompletionROUTINE используются в операциях перекрытого ввода-вывода (дискуссируются в последующей главе).

^ Функция WSARecvDisconnect

Эта функция обратна WSASendDisconnect и определена так:

// Code 3.18

int WSARecvDisconnect(

SOCKET s,

LPWSABUF lpInboundDisconnectData

);

Как и у WSASendDisconnect, ее параметрами являются описатель сокета соединения и действительная структура WSABUF для приема данных. Функция воспринимает только данные о закрытии соединения, отправленные с другой стороны функцией WSASendDisconnect, ее нельзя использовать для приема обыденных данных. К тому же, сходу после принятия данных она прекращает прием с удаленной стороны, что эквивалентно вызову shutdown с параметром SD_RECV.

^ Функция WSARecvEx

Эта функция — особое расширение Microsoft для Winsock 1. Она схожа recv во всем, не считая того, что параметр flags передается по ссылке. Это позволяет базисному поставщику задавать флаг MSG_PARTLAL.

// Code 3.19

int PASCAL FAR WSARecvEx(

SOCKET s,

char FAR * buf,

int len,

int * flags

);

Если приобретенные данные не составляют полного сообщения, в параметре flags ворачивается флаг MSG_PARTIAL. Он употребляется только с протоколами, нацеленными на передачу сообщений. Когда при принятии неполного сообщения флаг MSG_PARTIAL передается как часть параметра flags, функция заканчивается немедля, возвратив принятые данные. Если в буфере не хватает места, чтоб принять сообщение полностью, WSARecvEx возвратит ошибку WSAEMSGSIZE, а оставшиеся данные будут отброшены. Есть разница меж флагом MSG_PARTIAL и ошибкой WSAEMSGSIZE: в случае ошибки сообщение поступило полностью, но соответственный буфер очень мал для его приема. Флаги MSG_PEEK и MSG_OOB также можно использовать в WSARecvEx.





Возможно Вам будут интересны работы похожие на: Передача данных:


Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Похожый реферат

Cпециально для Вас подготовлен образовательный документ: Передача данных