read() с setsockopt() в C

Я пытаюсь написать серверно-клиентский код и застрял в одной точке. Я хочу, чтобы клиент читал в течение определенного времени и тайм-аута. Я попытался использовать setsockopt() с SO_RCVTIMEO, указав время в структуре timeval, но мой read() не ждет времени, которое я указываю в структуре timeval. Дело в том, что read() ожидает указанное время, если я просто использую read() после setsockopt(). Если я сначала вызываю write(), а затем read(), время ожидания функции read() истекает немедленно, не дожидаясь указанного времени, указанного в структуре timeval. Мой код показан ниже:

//пример клиентского кода

    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<netdb.h>


    void error(char *msg)
    {
        perror(msg);
        exit(1);
    }

    int main(int argc, char *argv[])
    {
        int a=1;
        fd_set readfds,writefds;
        int ready_for_reading,reading;
        struct timeval time_out;

        int sockfd,newsockfd,portno,n;
        struct sockaddr_in serv_addr;
        struct hostent *server;
    //  server=gethostbyname(argv[1]);
        char buffer[256];
        portno=atoi(argv[2]);
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        server=gethostbyname(argv[1]);
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_port=htons(portno);
        bcopy((char *)server->h_addr,
            (char *)&serv_addr.sin_addr.s_addr,
            server->h_length);
        time_out.tv_sec = 15;    // 15 seconds
            time_out.tv_usec = 0;    // 0 milliseconds

    //  sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(sockfd==-1)
            error("\nError creating socket");
    //      if(setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time_out, sizeof (time_out)))
    //               error("\n\tsetsockopt function has a problem\n");

        n=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
        if(n==-1)
            error("\nError connecting to server");
        printf("\nEnter client's msg:");
        fgets(buffer,255,stdin);
        n=write(sockfd,buffer,strlen(buffer));
        if(n<0)
            error("\nMsg not written to server");
        if(setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time_out, sizeof(time_out)))
            error("\n\tsetsockopt function has a problem\n");

    //  FD_ZERO(&readfds);
    //  FD_SET(sockfd,&readfds);

        n=read(sockfd,buffer,255);
    //  ready_for_reading=select(sockfd,&readfds,NULL,NULL,&time_out);
    //  printf("\nready_for_reading=%d",ready_for_reading);
    /*  if (ready_for_reading)
            {
              //  reading = read(newsockfd, buffer, 255);
                printf("Read, %d bytes from input : %s \n", n,buffer);
            }
            else
            {
                printf(" 10 Seconds are over - no data input \n");
                return 0;
            }
    */
        if(n<0)
            printf("\nMsg not read from server");
        if(n==0)
        {
            printf("\n No ack from server");
            return 0;
        }
        printf("\nServer's ack:%s\n",buffer);

    /*  if (ready_for_reading) 
        {
            //  reading = read(newsockfd, buffer, 255);
                printf("Read, %d bytes from input : %s \n", n,buffer);
            } 
        else 
        {
                    printf(" 10 Seconds are over - no data input \n");
            return 0;
            }
    */
        return 0;
    }   

В моем коде выше я хочу, чтобы время ожидания операции read() истекло через 15 секунд. Но время ожидания истекает немедленно. Мне нужна помощь!!!


person Rich    schedule 15.09.2012    source источник
comment
Возвращает ли чтение отрицательное значение?   -  person Ramy Al Zuhouri    schedule 15.09.2012
comment
нет .. read () возвращает «0», что, я думаю, означает «0» прочитанных байтов ...   -  person Rich    schedule 16.09.2012
comment
Вы проверили, установлено ли после setsockop errno?   -  person Tony The Lion    schedule 16.09.2012


Ответы (1)


Если read возвращает ноль, это означает, что соединение закрыто. Ждать нечего, поэтому оно не может ждать.

Кроме того, этот код не работает:

    printf("\nServer's ack:%s\n",buffer);

Вы можете использовать спецификатор формата %s только для печати строки в стиле C. То, как вы его использовали, никак не могло узнать, сколько байтов нужно напечатать, потому что это хранится только в переменной n на этом этапе вашего кода.

person David Schwartz    schedule 15.09.2012
comment
ох .. большое спасибо, Дэвид, что указал на это .. Я закрывал соединение на стороне сервера .. теперь это работает .. :) - person Rich; 16.09.2012
comment
@Richard: Обязательно исправьте другую ошибку, иначе она работает только по счастливой случайности. - person David Schwartz; 16.09.2012