Qual é o tamanho de um buffer de envio de soquete no Windows?

Com base no meu entendimento, cada soquete está associado a dois buffers, um buffer de envio e um buffer de recebimento, portanto, quando eu chamo osend() função, o que acontece é que os dados a serem enviados serão colocados no buffer de envio e agora é responsabilidade do Windows enviar o conteúdo desse buffer de envio para o outro lado.

Em um soquete de bloqueio, osend() A função não retorna até que todos os dados fornecidos tenham sido colocados no buffer de envio.

Então, qual é o tamanho do buffer de envio?

Eu executei o seguinte teste (enviando 1 GB de dados):

#include <stdio.h>

#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

#include <Windows.h>

int main()
{
    // Initialize Winsock
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);

    // Create socket
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);

    //----------------------

    // Connect to 192.168.1.7:12345
    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("192.168.1.7");
    address.sin_port = htons(12345);
    connect(s, (sockaddr*)&address, sizeof(address));

    //----------------------

    // Create 1 GB buffer ("AAAAAA...A")
    char *buffer = new char[1073741824];
    memset(buffer, 0x41, 1073741824);

    // Send buffer
    int i = send(s, buffer, 1073741824, 0);

    printf("send() has returned\nReturn value: %d\nWSAGetLastError(): %d\n", i, WSAGetLastError());

    //----------------------

    getchar();
    return 0;
}

Resultado:

send() has returned
Return value: 1073741824
WSAGetLastError(): 0

send() retornou imediatamente, isso significa que o buffer de envio tem um tamanho de pelo menos 1 GB?

Estas são algumas informações sobre o teste:

Estou usando um soquete de bloqueio de TCP.Eu conectei a uma máquina LAN.Versão do Windows cliente: Windows 7 Ultimate de 64 bits.Servidor Versão do Windows: Windows XP SP2 de 32 bits (instalado no Virtual Box).

Editar: Também tentei me conectar ao Google (173.194.116.18:80) e obtive os mesmos resultados.

Edição 2: Eu descobri algo estranho, definir o buffer de envio para um valor entre 64 KB e 130 KB fará com quesend() trabalhar como esperado!

int send_buffer = 64 * 1024;    // 64 KB
int send_buffer_sizeof = sizeof(int);
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)send_buffer, send_buffer_sizeof);

Edição 3: Acabou (graças a Harry Johnston) que eu useisetsockopt() de uma maneira incorreta, é assim que é usado:

setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&send_buffer, send_buffer_sizeof);

Configurando o buffer de envio para um valor entre 64 KB e 130 KBnão façosend() trabalhar como esperado,mas sim configurando o buffer de envio para0 torna o bloco (é o que eu notei de qualquer maneira, não tenho documentação para esse comportamento).

Então, minha pergunta agora é: onde posso encontrar uma documentação sobre comosend() (e talvez outras operações de soquete) funcionam no Windows?

questionAnswers(3)

yourAnswerToTheQuestion