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?