TCP server with select(), does not work because printf shows 3x to msg and msg comes with trash at the end and ends automatically

Asked

Viewed 23 times

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)'\0',  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)] = '\0';
                    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);


}

1 answer

0


An error you can see at first: you are receiving data in buffer using recv(), but you are using buffer in printf() as if it were a string ending in 0, and recv() does not guarantee this. A simple solution is place

buffer[n] = '\0';

immediately after recv(). You must also make the buffer size equal to (MAX_LEN+1) so that it fits this zero in case recv() has received MAX_LEN octets.

Another thing: a connection is marked as closed when recv() returns zero, i.e., it receives zero characters. It seems to me you’re not handling this case.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.