TCP server with select () does not work because printf shows 3x msg and msg comes with garbage at the end and it finishes automatically

0
void cria_server_tcp(int porto)
{
    struct sockaddr_in serveraddr, clientaddr;
    int fd_listen = cria_socket_tcp();
    int max_clientes = 20; //numero maximo de clientes em espera
    int addrlen;
    int *memset_r;
    int bind_r;
    int listen_r;

    memset_r=memset((void*)&serveraddr, (int)'
void cria_server_tcp(int porto)
{
    struct sockaddr_in serveraddr, clientaddr;
    int fd_listen = cria_socket_tcp();
    int max_clientes = 20; //numero maximo de clientes em espera
    int addrlen;
    int *memset_r;
    int bind_r;
    int listen_r;

    memset_r=memset((void*)&serveraddr, (int)'%pre%',  sizeof(serveraddr));
        if(memset_r==NULL){
            printf("Erro no memset para cliente (TCP).\n");
        exit(EXIT_FAILURE);
        }

    serveraddr.sin_family= AF_INET;
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
    serveraddr.sin_port=htons((u_short)porto);

    bind_r=bind(fd_listen, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
        if(bind_r == -1){
            printf("Erro no bind ao cliente (TCP).\n");
        exit(EXIT_FAILURE);
        }

    if(listen(fd_listen, max_clientes) < 0){
        printf("Erro a abrir socket para ouvir cliente (TCP).\n");
        exit(EXIT_FAILURE);
    }

        addrlen = sizeof(clientaddr);
        int fd;
        int n=0, len=0, maxlen=MAX_LEN;
        char buffer[MAX_LEN];
        char *auxbuffer = buffer;
        char msg[MAX_LEN];
        fd_set read_set;
        struct timeval timeout;
        int check_select;
        char ler[MAX_LEN];

        fd = accept(fd_listen, (struct sockaddr*)&clientaddr, &addrlen);
            if(fd == -1){
                printf("Erro a aceitar dados do cliente (TCP).\n");
                exit(EXIT_FAILURE);
            }

      timeout.tv_sec = 100;       /* timeout (secs.) */
      timeout.tv_usec = 0;      /* 0 microseconds */


        //corre indefinidamente
        while(1){

            FD_ZERO(&read_set);
            FD_SET(0, &read_set);
            FD_SET(fd, &read_set);
            check_select = select(fd + 1, &read_set, NULL, NULL, &timeout);

            if(check_select != 0 && check_select != -1)
            {
                if(FD_ISSET(fd, &read_set))
                {
                    n = recv(fd, buffer, maxlen, 0);
                    //printf("%d\n", n);

                    /*auxbuffer += n;
                    maxlen -= n;
                    len += n;*/

                    printf("Mensagem recebida: '%s'\n", buffer);
                    send(fd, msg, strlen(buffer), 0);
                    printf("entrei\n");
                }

                if(FD_ISSET(0, &read_set))
                {
                    scanf("%s", ler);
                    ler[strlen(ler)] = '%pre%';
                    read_stdin(ler, &fd);
                }
        }

        //corre enquanto a sessão do cliente estiver aberta
        /*while((n = recv(fd, auxbuffer, maxlen, 0)) > 0){

            auxbuffer += n;
            maxlen -= n;
            len += n;

            printf("Mensagem recebida: '%s'\n", buffer);

            send(fd, buffer, strlen(buffer), 0);
        }*/


    }

    close(fd);
    close(fd_listen);


}
', sizeof(serveraddr)); if(memset_r==NULL){ printf("Erro no memset para cliente (TCP).\n"); exit(EXIT_FAILURE); } serveraddr.sin_family= AF_INET; serveraddr.sin_addr.s_addr=htonl(INADDR_ANY); serveraddr.sin_port=htons((u_short)porto); bind_r=bind(fd_listen, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); if(bind_r == -1){ printf("Erro no bind ao cliente (TCP).\n"); exit(EXIT_FAILURE); } if(listen(fd_listen, max_clientes) < 0){ printf("Erro a abrir socket para ouvir cliente (TCP).\n"); exit(EXIT_FAILURE); } addrlen = sizeof(clientaddr); int fd; int n=0, len=0, maxlen=MAX_LEN; char buffer[MAX_LEN]; char *auxbuffer = buffer; char msg[MAX_LEN]; fd_set read_set; struct timeval timeout; int check_select; char ler[MAX_LEN]; fd = accept(fd_listen, (struct sockaddr*)&clientaddr, &addrlen); if(fd == -1){ printf("Erro a aceitar dados do cliente (TCP).\n"); exit(EXIT_FAILURE); } timeout.tv_sec = 100; /* timeout (secs.) */ timeout.tv_usec = 0; /* 0 microseconds */ //corre indefinidamente while(1){ FD_ZERO(&read_set); FD_SET(0, &read_set); FD_SET(fd, &read_set); check_select = select(fd + 1, &read_set, NULL, NULL, &timeout); if(check_select != 0 && check_select != -1) { if(FD_ISSET(fd, &read_set)) { n = recv(fd, buffer, maxlen, 0); //printf("%d\n", n); /*auxbuffer += n; maxlen -= n; len += n;*/ printf("Mensagem recebida: '%s'\n", buffer); send(fd, msg, strlen(buffer), 0); printf("entrei\n"); } if(FD_ISSET(0, &read_set)) { scanf("%s", ler); ler[strlen(ler)] = '%pre%'; read_stdin(ler, &fd); } } //corre enquanto a sessão do cliente estiver aberta /*while((n = recv(fd, auxbuffer, maxlen, 0)) > 0){ auxbuffer += n; maxlen -= n; len += n; printf("Mensagem recebida: '%s'\n", buffer); send(fd, buffer, strlen(buffer), 0); }*/ } close(fd); close(fd_listen); }
    
asked by anonymous 30.03.2018 / 01:15

1 answer

0

An error can be seen from the face: you are receiving buffered data using recv (), but it is using buffer in printf () as if it were a string ending in 0, and recv () does not guarantee this. A simple solution is put

buffer[n] = '
buffer[n] = '%pre%';
';

shortly after recv (). You should also make the buffer size equal to (MAX_LEN + 1) to fit this zero in case recv () has received MAX_LEN octets.

Another thing: a connection is flagged as closed when recv () returns zero, ie receives zero characters. It seems to me that you are not dealing with this case.

    
30.03.2018 / 04:12