1
I’m having trouble sending a 32k buffer from a client to a server. For example: I have an A program on one machine, which is the client, and a B program on another machine, which is the server. When the client connects via socket, and sends the buffer, on the server it appears that only 7k were sent, someone knows why this problem occurs?
Client code:
int sock, conecta;
struct sockaddr_in cliente;
char buffer[32768]
// PRENCHE BUFFER COM \0
memset(buffer, '.', sizeof(buffer));
// INICIALIZA O SOCKET
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Erro socket.");
exit(1);
}
// ESTRUTURA DO CLIENTE
cliente.sin_family = AF_INET; /* IPv4 */
cliente.sin_port = htons(15678); /* CONECTAR NA PORTA */
cliente.sin_addr.s_addr = inet_addr("127.0.0.1"); /* CONECTAR NO IP */
memset(&(cliente.sin_zero), '/0', 8);
printf("\nConectando ao servidor %s...\n", inet_ntoa(cliente.sin_addr));
// FAZ CONEXÃO COM O SERVIDOR
conecta = connect(sock, (struct sockaddr *)&cliente, sizeof(struct sockaddr));
if (conecta == -1) {
printf("Porta fechada\n");
exit(1);
} else
printf("Conexao sucedida.\n");
// ENVIA BUFFER DE 32K
enviarBuffer(sock, buffer, 32768);
Server code:
/* CRIANDO ESTRUTURA LOCAL(SERVIDOR) */
localServ.sin_family = AF_INET; /* IPv4 */
localServ.sin_port = htons(PORTA);
localServ.sin_addr.s_addr = INADDR_ANY; /* DECLARA COMO 0.0.0.0 PARA FUNCIONAR COM QUALQUER IP DISPONIVEL */
memset(&(localServ.sin_zero), '/0', 8);
if((sockServ = socket(AF_INET, SOCK_STREAM, 0)) == ERR_CONECT_DB) {
perror("Erro socket.");
exit(1);
}
/* DECLARAÇÃO DO SOCKET() BIND() E LISTEN() DO SERVIDOR */
if((bind(sockServ, (struct sockaddr *)&localServ, sizeof(struct sockaddr))) == ERR_CONECT_DB) { /* ASSOCIA O SOCKET CRIADO À UMA PORTA */
perror(("bind.\n"));
exit(1);
}
if((listen(sockServ, BACKLOG)) == ERR_CONECT_DB) { /* HABILITA CONEXÕES */
perror("listen.\n");
exit(1);
}
tamanho = sizeof(struct sockaddr_in);
while(1) {
if ((sockReceive = accept(sockServ, (struct sockaddr *)&remote, &tamanho)) < 0) {
perror("accept");
exit(1);
} else {
pid = fork();
if(pid == 0) { // SE PROCESSO FILHO ...
close(sockServ); // ENCERRA PROCESSO PAI
printf("Conexao recebida de %s:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
printf("PID: %d\n", getpid());
// RECEBE BUFFER DE 32K
if((nBytes = recv(sockReceive, buffer, 32768, 0)) < 0) {
perror("buffer");
close(sockReceive);
} else
printf("\nbuffer de solicitação recebido com %d Bytes\n", nBytes);
}
}
Cool, I think it worked!! Thanks ^^
– Vynstus
Another thing, this loop also serves to send the buffer, IE, use send function()?
– Vynstus
And it could also explain the need to do this?
– Vynstus
To send just one
send()
with the complete content. If it is necessary to break the data into pieces, this is done internally by thesend()
, is not the responsibility of the programmer.– pmg
Negative @pmg - send() can only send one piece of data, and you need to loop just like recv(). It does not guarantee the sending of all data!!! The difference is that usually the sending buffer has enough space to receive 64k or 128k at once. But if you try to send a really large buffer, or the connection is slow and the upload buffer is full, send() will return a lower value than the buffer.
– epx
Thanks @epx, note added in my reply.
– pmg
@pmg in the socket reference book, EINTR interruption is treated. It would not be interesting to include this in the response?
– lemoce
Thanks @lemoce, added links to the reference POSIX.1-2017
– pmg