Função send (winsock2.h)
A função send envia dados em um soquete conectado.
Sintaxe
int WSAAPI send(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags
);
Parâmetros
[in] s
Um descritor que identifica um soquete conectado.
[in] buf
Um ponteiro para um buffer que contém os dados a serem transmitidos.
[in] len
O comprimento, em bytes, dos dados no buffer apontados pelo parâmetro buf .
[in] flags
Um conjunto de sinalizadores que especificam a maneira como a chamada é feita. Esse parâmetro é construído usando o operador OR bit a bit com qualquer um dos valores a seguir.
Retornar valor
Se nenhum erro ocorrer, send retornará o número total de bytes enviados, que pode ser menor do que o número solicitado para ser enviado no parâmetro len . Caso contrário, um valor de SOCKET_ERROR é retornado e um código de erro específico pode ser recuperado chamando WSAGetLastError.
Código do erro | Significado |
---|---|
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função. | |
O subsistema de rede falhou. | |
O endereço solicitado é um endereço de transmissão, mas o sinalizador apropriado não foi definido. Chame setsockopt com a opção de soquete SO_BROADCAST para habilitar o uso do endereço de difusão. | |
Uma chamada do Windows Sockets 1.1 de bloqueio foi cancelada por meio de WSACancelBlockingCall. | |
Uma chamada do Windows Sockets 1.1 de bloqueio está em andamento ou o provedor de serviços ainda está processando uma função de retorno de chamada. | |
O parâmetro buf não está completamente contido em uma parte válida do espaço de endereço do usuário. | |
A conexão foi interrompida porque a atividade de manutenção de funcionamento detectou uma falha enquanto a operação estava em andamento. | |
Nenhum espaço de buffer disponível. | |
O soquete não está conectado. | |
O descritor não é um soquete. | |
MSG_OOB foi especificado, mas o soquete não é estilo de fluxo, como tipo SOCK_STREAM, não há suporte para dados OOB no domínio de comunicação associado a esse soquete ou o soquete é unidirecional e dá suporte apenas a operações de recebimento. | |
O soquete foi desligado; não é possível enviar em um soquete após o desligamento ter sido invocado com a definição de como SD_SEND ou SD_BOTH. | |
O soquete é marcado como não desbloqueio e a operação solicitada seria bloqueada. | |
O soquete é orientado a mensagens e a mensagem é maior do que o máximo suportado pelo transporte subjacente. | |
O host remoto não pode ser acessado desse host no momento. | |
O soquete não foi associado à associação ou um sinalizador desconhecido foi especificado ou MSG_OOB foi especificado para um soquete com SO_OOBINLINE habilitado. | |
O circuito virtual foi encerrado por causa do tempo limite ou outra falha. O aplicativo deve fechar o soquete porque ele não pode ser mais usado. | |
O circuito virtual foi redefinido pelo lado remoto executando um fechamento forçado ou por anulação. Para soquetes UDP, o host remoto não pôde entregar um datagrama UDP enviado anteriormente e respondeu com um pacote ICMP "Porta Inacessível". O aplicativo deve fechar o soquete porque ele não pode ser mais usado. | |
A conexão foi descartada, devido a uma falha de rede ou porque o sistema na outra extremidade ficou inativo sem aviso prévio. |
Comentários
A função send é usada para gravar dados de saída em um soquete conectado.
Para soquetes orientados a mensagens (família de endereços de AF_INET ou AF_INET6, tipo de SOCK_DGRAM e protocolo de IPPROTO_UDP, por exemplo), deve-se tomar cuidado para não exceder o tamanho máximo do pacote do provedor subjacente. O tamanho máximo do pacote de mensagem para um provedor pode ser obtido chamando getsockopt com o parâmetro optname definido como SO_MAX_MSG_SIZE para recuperar o valor da opção de soquete. Se os dados forem muito longos para passar atomicamente pelo protocolo subjacente, o erro WSAEMSGSIZE será retornado e nenhum dado será transmitido.
A conclusão bem-sucedida de uma função de envio não indica que os dados foram entregues e recebidos com êxito ao destinatário. Essa função indica apenas que os dados foram enviados com êxito.
Se nenhum espaço de buffer estiver disponível no sistema de transporte para manter os dados a serem transmitidos, o envio será bloqueado, a menos que o soquete tenha sido colocado no modo sem bloqueio. Em soquetes orientados ao fluxo sem bloqueio, o número de bytes gravados pode ser entre 1 e o comprimento solicitado, dependendo da disponibilidade do buffer nos computadores cliente e servidor. As funções select, WSAAsyncSelect ou WSAEventSelect podem ser usadas para determinar quando é possível enviar mais dados.
Chamar enviar com um parâmetro len de zero é permitido e será tratado por implementações como bem-sucedido. Nesses casos, send retornará zero como um valor válido. Para soquetes orientados a mensagens, um datagrama de transporte de comprimento zero é enviado.
O parâmetro flags pode ser usado para influenciar o comportamento da função além das opções especificadas para o soquete associado. A semântica da função send é determinada por todas as opções definidas anteriormente no soquete especificado no parâmetro s e pelo parâmetro flags passado para a função send .
A ordem das chamadas feitas para enviar também é a ordem na qual os buffers são transmitidos para a camada de transporte. send não deve ser chamado no mesmo soquete orientado a fluxo simultaneamente de threads diferentes, pois alguns provedores winsock podem dividir uma solicitação de envio grande em várias transmissões, e isso pode levar a intercalação de dados não intencionais de várias solicitações de envio simultâneas no mesmo soquete orientado a fluxo.
Código de exemplo
O exemplo a seguir demonstra o uso da função 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 exemplo
Para obter outro exemplo que usa a função send, consulte Introdução With Winsock.Notas sobre soquetes IrDA
- O arquivo de cabeçalho Af_irda.h deve ser incluído explicitamente.
Windows 8.1 e Windows Server 2012 R2: essa função tem suporte para aplicativos da Windows Store em Windows 8.1, Windows Server 2012 R2 e posteriores.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP] |
Servidor mínimo com suporte | Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP] |
Plataforma de Destino | Windows |
Cabeçalho | winsock2.h |
Biblioteca | Ws2_32.lib |
DLL | Ws2_32.dll |