Socket TCP in C

1

I'm having trouble sending a 32k buffer from a client to a server. For example: I have a program A on one machine, which is the client, and a program B on another machine, which is the server. When the client makes the socket connection, and sends the buffer, on the server it appears that only 7k have been sent, does anyone know why this problem occurs?

Client code:

int sock, conecta;
struct sockaddr_in cliente;

char buffer[32768]

// PRENCHE BUFFER COM 
/* 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);


                }
            }
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:

int sock, conecta;
struct sockaddr_in cliente;

char buffer[32768]

// PRENCHE BUFFER COM 
/* 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);


                }
            }
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);
    
asked by anonymous 30.06.2015 / 16:38

1 answer

3

You have to put recv() in a loop until it returns 0 .

char buffer[40000];
int bsize = 40000;
int blen = 0;

while (blen < bsize) {
    int bytes = recv(socket, buffer + blen, bsize - blen, 0); // recv() dentro dum ciclo
    if (bytes == 0) break;
    if (bytes == -1) /* erro */;
    blen += bytes;
}
buffer[blen] = 0; // se o buffer tiver texto e quiseres trata-lo como uma string

This is necessary because the internal operation of send() allows it to send chunks of the message in sequence . The process with read() must pick up every bit and re-build the original message.

    
30.06.2015 / 16:46