Compartir a través de


función send (winsock2.h)

La función send envía datos en un socket conectado.

Sintaxis

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

Parámetros

[in] s

Descriptor que identifica un socket conectado.

[in] buf

Puntero a un búfer que contiene los datos que se van a transmitir.

[in] len

Longitud, en bytes, de los datos del búfer al que apunta el parámetro buf .

[in] flags

Conjunto de marcas que especifican la forma en que se realiza la llamada. Este parámetro se construye mediante el operador OR bit a bit con cualquiera de los valores siguientes.

Valor Significado
MSG_DONTROUTE
Especifica que los datos no deben estar sujetos a enrutamiento. Un proveedor de servicios de Windows Sockets puede optar por omitir esta marca.
MSG_OOB
Envía datos OOB (socket de estilo de flujo, como solo SOCK_STREAM).

Valor devuelto

Si no se produce ningún error, send devuelve el número total de bytes enviados, que puede ser menor que el número solicitado para enviarse en el parámetro len . De lo contrario, se devuelve un valor de SOCKET_ERROR y se puede recuperar un código de error específico mediante una llamada a WSAGetLastError.

Código de error Significado
WSANOTINITIALISED
Debe producirse una llamada WSAStartup correcta antes de usar esta función.
WSAENETDOWN
Error en el subsistema de red.
WSAEACCES
La dirección solicitada es una dirección de difusión, pero no se ha establecido la marca adecuada. Llame a setsockopt con la opción de socket SO_BROADCAST para habilitar el uso de la dirección de difusión.
WSAEINTR
Se canceló una llamada de Bloqueo de Windows Sockets 1.1 a través de WSACancelBlockingCall.
WSAEINPROGRESS
Una llamada de Bloqueo de Windows Sockets 1.1 está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada.
WSAEFAULT
El parámetro buf no está completamente contenido en una parte válida del espacio de direcciones del usuario.
WSAENETRESET
Se interrumpió la conexión debido a que la actividad para mantener activa la conexión detectó un error durante la operación.
WSAENOBUFS
No hay espacio disponible en el búfer.
WSAENOTCONN
El socket no está conectado.
WSAENOTSOCK
El descriptor no es un socket.
WSAEOPNOTSUPP
MSG_OOB se especificó, pero el socket no es de tipo SOCK_STREAM, los datos OOB no se admiten en el dominio de comunicación asociado a este socket, o el socket es unidireccional y solo admite operaciones de recepción.
WSAESHUTDOWN
El socket se ha apagado; no es posible enviar en un socket después de que se haya invocado el apagado con cómo se establece en SD_SEND o SD_BOTH.
WSAEWOULDBLOCK
El socket está marcado como de no bloqueo y la operación solicitada supondría un bloqueo.
WSAEMSGSIZE
El socket está orientado a mensajes y el mensaje es mayor que el máximo admitido por el transporte subyacente.
WSAEHOSTUNREACH
No se puede acceder al host remoto desde este host en este momento.
WSAEINVAL
El socket no se ha enlazado con bind o se especificó una marca desconocida, o MSG_OOB se especificó para un socket con SO_OOBINLINE habilitado.
WSAECONNABORTED
Se finalizó el circuito virtual debido a un tiempo de espera agotado u otro error. La aplicación debería cerrar el socket porque ya no se puede usar.
WSAECONNRESET
El lado remoto que ejecuta un cierre firme o de anulación restableció el circuito virtual. En el caso de los sockets UDP, el host remoto no pudo entregar un datagrama UDP enviado previamente y respondió con un paquete ICMP "Puerto inaccesible". La aplicación debería cerrar el socket porque ya no se puede usar.
WSAETIMEDOUT
Se ha quitado la conexión, debido a un error de red o porque el sistema en el otro extremo se ha reducido sin previo aviso.

Comentarios

La función send se usa para escribir datos salientes en un socket conectado.

En el caso de sockets orientados a mensajes (familia de direcciones de AF_INET o AF_INET6, tipo de SOCK_DGRAM y protocolo de IPPROTO_UDP, por ejemplo), se debe tener cuidado de no superar el tamaño máximo de paquete del proveedor subyacente. El tamaño máximo del paquete de mensaje para un proveedor se puede obtener llamando a getsockopt con el parámetro optname establecido en SO_MAX_MSG_SIZE para recuperar el valor de la opción de socket. Si los datos son demasiado largos para pasarse atómicamente a través del protocolo subyacente, se devuelve el error WSAEMSGSIZE y no se transmite ningún dato.

La finalización correcta de una función de envío no indica que los datos se entregaron y recibieron correctamente al destinatario. Esta función solo indica que los datos se enviaron correctamente.

Si no hay espacio de búfer disponible en el sistema de transporte para contener los datos que se van a transmitir, el envío se bloqueará a menos que el socket se haya colocado en modo de no bloqueo. En sockets orientados a flujos sin bloqueo, el número de bytes escritos puede estar entre 1 y la longitud solicitada, en función de la disponibilidad del búfer en los equipos cliente y servidor. Las funciones select, WSAAsyncSelect o WSAEventSelect se pueden usar para determinar cuándo es posible enviar más datos.

La llamada a send con un parámetro len de cero está permitida y se tratará mediante implementaciones como correctas. En tales casos, send devolverá cero como un valor válido. En el caso de los sockets orientados a mensajes, se envía un datagrama de transporte de longitud cero.

El parámetro flags se puede usar para influir en el comportamiento de la función más allá de las opciones especificadas para el socket asociado. La semántica de la función de envío viene determinada por las opciones establecidas anteriormente en el socket especificado en el parámetro s y el parámetro flags pasado a la función send .

El orden de las llamadas realizadas para enviar también es el orden en que los búferes se transmiten a la capa de transporte. no se debe llamar a send en el mismo socket orientado a secuencias simultáneamente desde diferentes subprocesos, ya que algunos proveedores de Winsock pueden dividir una solicitud de envío grande en varias transmisiones, y esto puede provocar que los datos no deseados intercalen desde varias solicitudes de envío simultáneas en el mismo socket orientado a flujos.

Nota Al emitir una llamada de Winsock de bloqueo como enviar, Winsock puede que tenga que esperar un evento de red antes de que se pueda completar la llamada. Winsock realiza una espera alertable en esta situación, que se puede interrumpir mediante una llamada de procedimiento asincrónica (APC) programada en el mismo subproceso. La emisión de otra llamada winsock de bloqueo dentro de un APC que interrumpió una llamada de Winsock de bloqueo en curso en el mismo subproceso provocará un comportamiento indefinido y los clientes winsock nunca deben intentarlo.
 

Código de ejemplo

En el ejemplo siguiente se muestra el uso de la función 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;
}

Código de ejemplo

Para obtener otro ejemplo que use la función send, consulte Introducción With Winsock.

Notas para sockets IrDA

  • El archivo de encabezado Af_irda.h debe incluirse explícitamente.
Windows Phone 8: esta función es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.

Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado winsock2.h
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

Introducción con Winsock

WSAAsyncSelect

WSAEventSelect

Funciones winsock

Referencia de Winsock

recv

recvfrom

select

sendto

socket