Поделиться через


функция send (winsock2.h)

Функция отправки отправляет данные в подключенный сокет.

Синтаксис

int WSAAPI send(
  [in] SOCKET     s,
  [in] const char *buf,
  [in] int        len,
  [in] int        flags
);

Параметры

[in] s

Дескриптор, определяющий подключенный сокет.

[in] buf

Указатель на буфер, содержащий передаваемые данные.

[in] len

Длина (в байтах) данных в буфере, на которые указывает параметр buf .

[in] flags

Набор флагов, указывающих способ вызова. Этот параметр создается с помощью побитового оператора OR с любым из следующих значений.

Значение Значение
MSG_DONTROUTE
Указывает, что данные не должны подвергаться маршрутизации. Поставщик службы Windows Sockets может игнорировать этот флаг.
MSG_OOB
Отправляет данные OOB (только сокет в стиле потока, например SOCK_STREAM).

Возвращаемое значение

Если ошибка не возникает, функция send возвращает общее количество отправленных байтов, которое может быть меньше числа, запрошенного для отправки в параметре len . В противном случае возвращается значение SOCKET_ERROR, а определенный код ошибки можно получить, вызвав WSAGetLastError.

Код ошибки Значение
WSANOTINITIALISED
Перед использованием этой функции должен произойти успешный вызов WSAStartup .
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEACCES
Запрошенный адрес является широковещательным, но соответствующий флаг не установлен. Вызовите setsockopt с параметром сокета SO_BROADCAST, чтобы разрешить использование широковещательного адреса.
WSAEINTR
Блокирующий вызов Windows Sockets 1.1 был отменен через WSACancelBlockingCall.
WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEFAULT
Параметр buf не полностью содержится в допустимой части адресного пространства пользователя.
WSAENETRESET
Подключение было разорвано из-за ошибки во время выполнения операции.
WSAENOBUFS
Нет свободного места в буфере.
WSAENOTCONN
Сокет не подключен.
WSAENOTSOCK
Дескриптор не является сокетом.
WSAEOPNOTSUPP
MSG_OOB указано, но сокет не является потоковым, например тип SOCK_STREAM, данные OOB не поддерживаются в домене связи, связанном с этим сокетом, или сокет является однонаправленным и поддерживает только операции получения.
WSAESHUTDOWN
Сокет был выключен; невозможно выполнить отправку в сокет после вызова завершения работыс параметром SD_SEND или SD_BOTH.
WSAEWOULDBLOCK
Сокет помечается как неблокировочный, и запрошенная операция будет блокироваться.
WSAEMSGSIZE
Сокет ориентирован на сообщения, и сообщение больше максимального значения, поддерживаемого базовым транспортом.
WSAEHOSTUNREACH
В настоящее время с этого узла не удается связаться с удаленным узлом.
WSAEINVAL
Сокет не был привязан с помощью привязки, или был указан неизвестный флаг, или MSG_OOB был указан для сокета с включенным SO_OOBINLINE.
WSAECONNABORTED
Виртуальное подключение разорвано из-за тайм-аута или иного сбоя. Приложение должно закрыть сокет, поскольку он больше не может использоваться.
WSAECONNRESET
Виртуальное подключение было сброшено удаленной стороной путем прерывания. Для сокетов UDP удаленный узел не смог доставить ранее отправленную датаграмму UDP и ответил пакетом ICMP "Порт недоступен". Приложение должно закрыть сокет, поскольку он больше не может использоваться.
WSAETIMEDOUT
Подключение было прервано из-за сбоя сети или из-за того, что система на другом конце не работает без предварительного уведомления.

Комментарии

Функция send используется для записи исходящих данных в подключенный сокет.

Для сокетов, ориентированных на сообщения (например, семейство адресов AF_INET или AF_INET6, тип SOCK_DGRAM и протокол IPPROTO_UDP), следует соблюдать осторожность, чтобы не превышать максимальный размер пакета базового поставщика. Максимальный размер пакета сообщений для поставщика можно получить, вызвав метод getsockopt с параметром optname , равным SO_MAX_MSG_SIZE для получения значения параметра socket. Если данные слишком длинны для атомарной передачи через базовый протокол, возвращается ошибка WSAEMSGSIZE и данные не передаются.

Успешное завершение функции отправки не означает, что данные были успешно доставлены и получены получателю. Эта функция только указывает, что данные были успешно отправлены.

Если в транспортной системе нет буферного пространства для хранения передаваемых данных, отправка будет блокироваться, если сокет не был помещен в неблокировочный режим. В неблокированных сокетах, ориентированных на поток, число записанных байтов может составлять от 1 до требуемой длины в зависимости от доступности буфера как на клиентском, так и на серверном компьютерах. Функции select, WSAsyncSelect или WSAEventSelect можно использовать для определения возможности отправки дополнительных данных.

Вызов отправки с параметром len , равным нулю, допустим и будет рассматриваться реализациями как успешная. В таких случаях send возвращает ноль в качестве допустимого значения. Для сокетов, ориентированных на сообщения, отправляется транспортная датаграмма нулевой длины.

Параметр flags можно использовать для влияния на поведение функции за пределами параметров, указанных для связанного сокета. Семантика функции отправки определяется любыми параметрами, ранее заданными в сокете, указанном в параметре s , и параметром flags, переданным функции отправки .

Порядок вызовов, выполненных для отправки , также является порядком передачи буферов на транспортный уровень. Отправка не должна вызываться в одном потокоориентированном сокете одновременно из разных потоков, так как некоторые поставщики Winsock могут разделить большой запрос на отправку на несколько передач, что может привести к непреднамеренное чередование данных из нескольких одновременных запросов на отправку в одном и том же сокете, ориентированном на поток.

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

Пример кода

В следующем примере показано использование функции send .
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 27015

int main() {

    //----------------------
    // Declare and initialize variables.
    int iResult;
    WSADATA wsaData;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    int recvbuflen = DEFAULT_BUFLEN;
    char *sendbuf = "Client: sending data test";
    char recvbuf[DEFAULT_BUFLEN] = "";

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port of the server to be connected to.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( DEFAULT_PORT );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if (iResult == SOCKET_ERROR) {
        wprintf(L"connect failed with error: %d\n", WSAGetLastError() );
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
  }

    //----------------------
    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        wprintf(L"send failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %d\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            wprintf(L"Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            wprintf(L"Connection closed\n");
        else
            wprintf(L"recv failed with error: %d\n", WSAGetLastError());

    } while( iResult > 0 );


    // close the socket
    iResult = closesocket(ConnectSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"close failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    WSACleanup();
    return 0;
}

Пример кода

Другой пример, в котором используется функция отправки, см. в разделе начало работы с Помощью Winsock.

Примечания для сокетов IrDA

  • Файл заголовка Af_irda.h должен быть явно включен.
Windows Phone 8. Эта функция поддерживается для приложений Магазина Windows Phone на Windows Phone 8 и более поздних версиях.

Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версиях.

Требования

Требование Значение
Минимальная версия клиента Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header winsock2.h
Библиотека Ws2_32.lib
DLL Ws2_32.dll

См. также раздел

начало работы с Winsock

WSAsyncSelect

WSAEventSelect

Функции Winsock

Справочник по Winsock

Recv

recvfrom

select

Sendto

Сокета